Showing posts with label reading. Show all posts
Showing posts with label reading. Show all posts

Monday, March 19, 2012

Choosing values for primary keys

Hello group:

I've done alot of reading on this subject somewhat and have found that
many people have many different opinions on this subject. My question
centers mainly around using a lookup table to enable users to select a
pre-defined list of values.

I have developed a practice myself of avoiding AutoNumber type data
fields for primary keys where the primary key will be related to a
child table. Nevertheless, what do most users do with lookup tables?
My thoughts are to create a small key value for each value in the
lookup table. For example:

I might have a Carriers table which shows a list of carriers that I
might ship an order by. One of the entries may be 'Air Freight -
Overnight', or 'Air Freight - 2nd Day Air'. I've seen a few examples
where the primary key field for each entry like these would be
autonumber, or at least, a numeric value. What I like to do is create
my own key, like for 'Air Freight - Overnight', I might use 'AFO' for
the key, and for 'Air Freight - 2nd Day Air', I might use 'AF2'. Any
thoughts on this? Mine are that even tho the users may never see this
value - I, as the developer will see it and I tend to prefer a key
value based on real data that means something other than an
auto-incremented number. In referencing the well-known Northwind.mdb
database, I noticed their Categories table used a number field value,
like 1, 2, 3...etc, but their customers table used values like
'ALFKI' to represent their key values.

What are some other thoughts out there? I'm working with Access
currently, but this project is about to move to SQL Server.

JamesI can't speak from much experience (only actually created a few small
tables...) but in large tables, you'll save space using a numeric value
I think. A 32 bit value will give you LOTS of unique numbers for rows.
In your example, 3 ascii characters is still shorter (24 bits.)
However if you end up using lots of long-ish keys, you'll eat up lots of
extra bits.

However, you can see that I use lots of letters to say very little, so
who am I to comment on space?! :)

Just my $.02...trying not to lurk so much!

-gabe

James wrote:
> Hello group:
> I've done alot of reading on this subject somewhat and have found that
> many people have many different opinions on this subject. My question
> centers mainly around using a lookup table to enable users to select a
> pre-defined list of values.
> I have developed a practice myself of avoiding AutoNumber type data
> fields for primary keys where the primary key will be related to a
> child table. Nevertheless, what do most users do with lookup tables?
> My thoughts are to create a small key value for each value in the
> lookup table. For example:
> I might have a Carriers table which shows a list of carriers that I
> might ship an order by. One of the entries may be 'Air Freight -
> Overnight', or 'Air Freight - 2nd Day Air'. I've seen a few examples
> where the primary key field for each entry like these would be
> autonumber, or at least, a numeric value. What I like to do is create
> my own key, like for 'Air Freight - Overnight', I might use 'AFO' for
> the key, and for 'Air Freight - 2nd Day Air', I might use 'AF2'. Any
> thoughts on this? Mine are that even tho the users may never see this
> value - I, as the developer will see it and I tend to prefer a key
> value based on real data that means something other than an
> auto-incremented number. In referencing the well-known Northwind.mdb
> database, I noticed their Categories table used a number field value,
> like 1, 2, 3...etc, but their customers table used values like
> 'ALFKI' to represent their key values.
> What are some other thoughts out there? I'm working with Access
> currently, but this project is about to move to SQL Server.
>
> James|||[posted and mailed, please reply in news]

James (dragonzfang@.hotmail.com) writes:
> I might have a Carriers table which shows a list of carriers that I
> might ship an order by. One of the entries may be 'Air Freight -
> Overnight', or 'Air Freight - 2nd Day Air'. I've seen a few examples
> where the primary key field for each entry like these would be
> autonumber, or at least, a numeric value. What I like to do is create
> my own key, like for 'Air Freight - Overnight', I might use 'AFO' for
> the key, and for 'Air Freight - 2nd Day Air', I might use 'AF2'. Any
> thoughts on this? Mine are that even tho the users may never see this
> value - I, as the developer will see it and I tend to prefer a key
> value based on real data that means something other than an
> auto-incremented number. In referencing the well-known Northwind.mdb
> database, I noticed their Categories table used a number field value,
> like 1, 2, 3...etc, but their customers table used values like
> 'ALFKI' to represent their key values.

In the system I work, we use both mnemonic codes and numeric keys
(which rarely are IDENTITY values, but we generate them ourselves).
But we do not pick them at random.

Basically, if the table is pre-loaded, that is we define the data in
the table, the key is a good. This is because we may have to refer to
the key value in our SQL code (or client code), and using numeric values
may easily cause errors.

On the other hand, if the data in the table is user-entered, the key is
numeric. Because who would generate the codes in this case? There are a
few tables with user-entered data where the key is actually a code,
but this is when there is a natural code to pick. Prime examples are
countries and currencies.

(There are also pre-loaded tables with numeric keys. But I didn't
design them. Or they were accidents. :-)

--
Erland Sommarskog, SQL Server MVP, sommar@.algonet.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||James Lankford (dragonzfang@.hotmail.com) writes:
> In my Carriers table example, this is mainly just a lookup table, values
> are not likely to change often. If a new code needs to be defined, then
> the administrator can simply create his/her own unique key for the new
> entry.

We usually have a GUI for this sort of thing, but as you say, a lot this
data is highly static once it is in place.

> In the case of header/detail, parent to child table examples, I can see
> where having an autonumber generated key value is very beneficial. The
> two tables would still be linked via an invoice number, for example -
> but yet the autonumber key ID would serve as the unique identifer for
> the row. If the table becomes corrupted and needs to be rebuilt, or
> exported to another table, then it doesn't matter if the ID #'s change -
> nothing else is really "depending" upon it, and it still serves to
> uniquely identify that row.

For this kind of example, I prefer to have (InvoiceNo, RowNo) as the
key for the child table.

--
Erland Sommarskog, SQL Server MVP, sommar@.algonet.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp

Choosing Indexes

After doing some reading, I'd like some expert opinions on choosing indexes
for several scenarios.
1) One book said that you should almost index foreign keys in a table since
lookups are more inefficient without them. I have tables with up to ten FKs
used mostly for lookups from/joins with the PK table (e.g. marital status,
education level, etc.). Each of these PK lookup tables only have 3-10
possible values. However, pulling info from these PKs to display the linked
items is a frequent event and many times a day a massive report effectively
denormalizes everything for any individual customer.
Generally, is it worth the overhead to index foreign keys in one table for
primary key tables that have a handful of values?
2) If I have a web application for numerous companies that each have their
own customers, and when the folks from one company are using the application
they only see their customers one at a time or an alphabetical list (a
pretty common scenario I would think), what is the best way to index
CompanyID (a FK to a Company PK table), CustLastName, CustFirstName?
Is it better to have three distinct indexes? Which one should be the optimal
for a clustered index? (I would think CompanyID since it is used for almost
every query except for individual customers which are already indexed by
being a PK as CustomerID)
Or, should all of these be rolled into one composite index? If these are
rolled into a composite index, is there any value at all for still having
distinct indexes for these three columns? Would you still need an index for
the company FK join to the PK Company table, e.g. to display the company
name?
Even though the CompanyID is not as selective as the combination of first
name and last name, I would think a clustered index of CompanyID,
CustLastName, CustFirstName would do the trick without any other indices.
But maybe a separate index for CompanyID (for company information joins)?
Thanks for any tips.1) yes, otherwise you will end up doing table scans. With the indexes in
place you will scan the index which is much more efficient.
2) yes, always go from most restrictive to least restrict. You probably have
more first names, than last names and more last names than companies, hence
the index should look like companyID, LastName, Firstname. I would use one
index but it really depends. If most of your queries are like this
select * from tablename where companyid=1 and lastname =smith and
firstname=don the index should be on companyid, lastname and then first
name, however if you query on lastnames or firstnames you should have an
index on each of these columns as well.
Use a clustered index if you are doing a scan ie select * from tablename
where companyid>100, otherwise if you are only returning a few values use a
non clustered index.
HTH
--
Hilary Cotter
Director of Text Mining and Database Strategy
RelevantNOISE.Com - Dedicated to mining blogs for business intelligence.
This posting is my own and doesn't necessarily represent RelevantNoise's
positions, strategies or opinions.
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Looking for a FAQ on Indexing Services/SQL FTS
http://www.indexserverfaq.com
"Don Miller" <nospam@.nospam.com> wrote in message
news:Obu59EP1GHA.324@.TK2MSFTNGP05.phx.gbl...
> After doing some reading, I'd like some expert opinions on choosing
> indexes
> for several scenarios.
> 1) One book said that you should almost index foreign keys in a table
> since
> lookups are more inefficient without them. I have tables with up to ten
> FKs
> used mostly for lookups from/joins with the PK table (e.g. marital status,
> education level, etc.). Each of these PK lookup tables only have 3-10
> possible values. However, pulling info from these PKs to display the
> linked
> items is a frequent event and many times a day a massive report
> effectively
> denormalizes everything for any individual customer.
> Generally, is it worth the overhead to index foreign keys in one table for
> primary key tables that have a handful of values?
> 2) If I have a web application for numerous companies that each have their
> own customers, and when the folks from one company are using the
> application
> they only see their customers one at a time or an alphabetical list (a
> pretty common scenario I would think), what is the best way to index
> CompanyID (a FK to a Company PK table), CustLastName, CustFirstName?
> Is it better to have three distinct indexes? Which one should be the
> optimal
> for a clustered index? (I would think CompanyID since it is used for
> almost
> every query except for individual customers which are already indexed by
> being a PK as CustomerID)
> Or, should all of these be rolled into one composite index? If these are
> rolled into a composite index, is there any value at all for still having
> distinct indexes for these three columns? Would you still need an index
> for
> the company FK join to the PK Company table, e.g. to display the company
> name?
> Even though the CompanyID is not as selective as the combination of first
> name and last name, I would think a clustered index of CompanyID,
> CustLastName, CustFirstName would do the trick without any other indices.
> But maybe a separate index for CompanyID (for company information
> joins)?
> Thanks for any tips.
>|||Thanks for the advice, but I'm not sure if I understand all of your answers.
> 1) yes, otherwise you will end up doing table scans. With the indexes in
> place you will scan the index which is much more efficient.
Even faster than a table scan of only 5-10 rows total?
> 2) yes, always go from most restrictive to least restrict. You probably
have
> more first names, than last names and more last names than companies,
hence
> the index should look like companyID, LastName, Firstname.
So, if you go from most restrictive to least restrictive shouldn't the index
be in the exact opposite order? (e.g. FirstName, LastName, CompanyID)
> I would use one
> index but it really depends. If most of your queries are like this
> select * from tablename where companyid=1 and lastname =smith and
> firstname=don the index should be on companyid, lastname and then first
> name,
Most of my queries are probably more like this
select * from tablename where companyID = 1 order by lastname, firstname
> Use a clustered index if you are doing a scan ie select * from tablename
> where companyid>100, otherwise if you are only returning a few values use
a
> non clustered index.
The companyID will always be just one value and not a range. With that said,
maybe the LastName, FirstName should be the clustered choice with a
non-clustered index for companyID?
Thanks again for your help.|||Hi Hilary
Why is a clustered index better for a scan? Aren't all indexes sorted &
therefore equally beneficial for scans? Non-clustered actually indexes more
efficient for scans due to their higher page / row storage density..
The only thing a clustered index can do better than a non-clustered index is
cover the SELECT *, as it contains all columns, which definitely makes your
advice right in this case, but I think your rationale isn't clear.
I'm starting a series of short articles, intended to debunk the many myths
about clustered indexes on my blog, including the classic "clustered indexes
are better for range scans". I started this series a couple of days ago,
covering the bookmark lookup problem but I'll cover this specific issue soon
(it's definitely bogus):
http://blogs.sqlserver.org.au/blogs/greg_linwood/archive/2006/09/10/363.aspx
Regards,
Greg Linwood
SQL Server MVP
"Hilary Cotter" <hilary.cotter@.gmail.com> wrote in message
news:OUziSWQ1GHA.1256@.TK2MSFTNGP04.phx.gbl...
> 1) yes, otherwise you will end up doing table scans. With the indexes in
> place you will scan the index which is much more efficient.
> 2) yes, always go from most restrictive to least restrict. You probably
> have more first names, than last names and more last names than companies,
> hence the index should look like companyID, LastName, Firstname. I would
> use one index but it really depends. If most of your queries are like this
> select * from tablename where companyid=1 and lastname =smith and
> firstname=don the index should be on companyid, lastname and then first
> name, however if you query on lastnames or firstnames you should have an
> index on each of these columns as well.
> Use a clustered index if you are doing a scan ie select * from tablename
> where companyid>100, otherwise if you are only returning a few values use
> a non clustered index.
> HTH
> --
> Hilary Cotter
> Director of Text Mining and Database Strategy
> RelevantNOISE.Com - Dedicated to mining blogs for business intelligence.
> This posting is my own and doesn't necessarily represent RelevantNoise's
> positions, strategies or opinions.
> Looking for a SQL Server replication book?
> http://www.nwsu.com/0974973602.html
> Looking for a FAQ on Indexing Services/SQL FTS
> http://www.indexserverfaq.com
>
> "Don Miller" <nospam@.nospam.com> wrote in message
> news:Obu59EP1GHA.324@.TK2MSFTNGP05.phx.gbl...
>> After doing some reading, I'd like some expert opinions on choosing
>> indexes
>> for several scenarios.
>> 1) One book said that you should almost index foreign keys in a table
>> since
>> lookups are more inefficient without them. I have tables with up to ten
>> FKs
>> used mostly for lookups from/joins with the PK table (e.g. marital
>> status,
>> education level, etc.). Each of these PK lookup tables only have 3-10
>> possible values. However, pulling info from these PKs to display the
>> linked
>> items is a frequent event and many times a day a massive report
>> effectively
>> denormalizes everything for any individual customer.
>> Generally, is it worth the overhead to index foreign keys in one table
>> for
>> primary key tables that have a handful of values?
>> 2) If I have a web application for numerous companies that each have
>> their
>> own customers, and when the folks from one company are using the
>> application
>> they only see their customers one at a time or an alphabetical list (a
>> pretty common scenario I would think), what is the best way to index
>> CompanyID (a FK to a Company PK table), CustLastName, CustFirstName?
>> Is it better to have three distinct indexes? Which one should be the
>> optimal
>> for a clustered index? (I would think CompanyID since it is used for
>> almost
>> every query except for individual customers which are already indexed by
>> being a PK as CustomerID)
>> Or, should all of these be rolled into one composite index? If these are
>> rolled into a composite index, is there any value at all for still having
>> distinct indexes for these three columns? Would you still need an index
>> for
>> the company FK join to the PK Company table, e.g. to display the company
>> name?
>> Even though the CompanyID is not as selective as the combination of first
>> name and last name, I would think a clustered index of CompanyID,
>> CustLastName, CustFirstName would do the trick without any other indices.
>> But maybe a separate index for CompanyID (for company information
>> joins)?
>> Thanks for any tips.
>>
>|||On Sun, 10 Sep 2006 10:58:40 -0500, Don Miller wrote:
>After doing some reading, I'd like some expert opinions on choosing indexes
>for several scenarios.
Hi Don,
Here are mine. They are the diametrically opposite of Hilary's opinions,
just to confuse you <eg>
>1) One book said that you should almost index foreign keys in a table since
>lookups are more inefficient without them. I have tables with up to ten FKs
>used mostly for lookups from/joins with the PK table (e.g. marital status,
>education level, etc.). Each of these PK lookup tables only have 3-10
>possible values. However, pulling info from these PKs to display the linked
>items is a frequent event and many times a day a massive report effectively
>denormalizes everything for any individual customer.
>Generally, is it worth the overhead to index foreign keys in one table for
>primary key tables that have a handful of values?
In cases like this, with the referred table holding marital status,
education level, etc, indexes on the foreign key columns are often not
needed. Though it depends on the nature of your queries. If you often
query for female university level people or similar, indexes on those
columns *MIGHT* get used. But for most queries, I expect SQL Server to
filter rows based on other (more restrictive) criteria in the SELECT,
then use bookmark lookup or a hash join to find the english name for the
gender code, marital status code and education level code.
Indexes on foreign key columns are mainly used to check the constraint
on changes in the referenced table (which, in the case of marital status
and education level, should be extremely rare - the contents of those
tables are alomst constant) or when a very efficient filter can be
applied to the referenced table (which is often the case between
referencing table that hold non-constant data, such as orders and order
details, or orders and customers).
>2) If I have a web application for numerous companies that each have their
>own customers, and when the folks from one company are using the application
>they only see their customers one at a time or an alphabetical list (a
>pretty common scenario I would think), what is the best way to index
>CompanyID (a FK to a Company PK table), CustLastName, CustFirstName?
For queries like that, a clustered index no (CompanyID, CustLastName,
CustFirstName) is best. The engine can use the index structure to find
the first matching row in an instant; after that, it can navigate the
logical order of the data in the clustered index to find all rows for
the same company, and they'll already be in the order required. (It
might help to include CompanyID as the first column in the ORDER BY
clause.)
Note that, contrary to popular belief, more or less restrictive should
NOT be the first consideration for the order of columns in an index. You
should start with hhow the columns are used; restrictiveness comes only
second. If most of your searches are based on last name only, then last
name should be the first column in the index, whether restrictive or
not. If most searches are based on all three columns, then the order
doesn't matter for those searches (though statistics will be slightly
better if the most restrictive column is first). If all kinds of
searches are mixed, then you should have the most restrictive column as
the first in the index - and you might consider addition indexes for
searches that can't use the index.
>Is it better to have three distinct indexes? Which one should be the optimal
>for a clustered index? (I would think CompanyID since it is used for almost
>every query except for individual customers which are already indexed by
>being a PK as CustomerID)
I don't think three seperate indexes is a good idea. That might work if
you often search on first name only, often search on last name only, and
often search on CompanyID only. For searches on two or all three
columns, SQL Server *can* use operations that use all three tables, then
combine the intermediate results from those index searches - but the
overhead of that is quite costly, so it'll very often just use one index
to narrow down the search a bit, then search the rest by accessing all
rows and checking the values.
If you do use three indexes, than I think that CompanyID might indeed be
the best choice, but I'd try different options to make sure. Of course,
this also depends on the nature of other queries - above, you outlines
one typical query, but iff there are others as well, you should include
them in your analysis.
And I agree that searches for individual customers would benefit from an
index on CustomerID; since this is your key, the index shoould already
exist. If you've used default options, it's the clustered index - I
suggest that yoou change it to a nonclustered index, so that you can
have (CompanyID, CustLastName, CustFirstName) as clustered index. The
search for an individual customer results in just a single bookmark
lookup, which is quite inexpensive. It's the searches for a range of
rows where repeated bookmark lookups get expensive.
>Or, should all of these be rolled into one composite index? If these are
>rolled into a composite index, is there any value at all for still having
>distinct indexes for these three columns? Would you still need an index for
>the company FK join to the PK Company table, e.g. to display the company
>name?
Some situations might benefit from additional indexes on the single
columns (especially on the columns that are NOT first in the composite
index).
Finding company name based on CompanyID will in almost all cases require
an index on the CompanyID column in the Companies table - which should
be there already if you didn;t forget the primary key constraint.
>Even though the CompanyID is not as selective as the combination of first
>name and last name, I would think a clustered index of CompanyID,
>CustLastName, CustFirstName would do the trick without any other indices.
>But maybe a separate index for CompanyID (for company information joins)?
With that clustered index, a seperate index on only CompanyID would only
give you some benefit in rare cases where the query is covered by this
index - the benefit will probably not outweigh the cost of maintaining
an additional index.
--
Hugo Kornelis, SQL Server MVP|||1) well probably not. But for larger tables indexes are faster than table
scans.
2) Well when I think most restrictive I think of a value which returns the
fewest results. So as there are fewer company id's than Smiths and even
fewer company id's than Johns, I would argue that it would go some
companyID, LastName and then FirstName.
So consider John Smith where there are 200 john smiths per company id and
there are 20 companies. If you search on FirstName, LastName, CompanyID you
would return 200*20 rows to the filtering condition which filters out
company id's. Then 200 are returned. If you go Company ID, then Names, 200
rows are returned to the filtering condition and then 200 remain in the
filter.
Make sense?
--
Hilary Cotter
Director of Text Mining and Database Strategy
RelevantNOISE.Com - Dedicated to mining blogs for business intelligence.
This posting is my own and doesn't necessarily represent RelevantNoise's
positions, strategies or opinions.
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Looking for a FAQ on Indexing Services/SQL FTS
http://www.indexserverfaq.com
"Don Miller" <nospam@.nospam.com> wrote in message
news:uXL6NgQ1GHA.4648@.TK2MSFTNGP04.phx.gbl...
> Thanks for the advice, but I'm not sure if I understand all of your
> answers.
>> 1) yes, otherwise you will end up doing table scans. With the indexes in
>> place you will scan the index which is much more efficient.
> Even faster than a table scan of only 5-10 rows total?
>> 2) yes, always go from most restrictive to least restrict. You probably
> have
>> more first names, than last names and more last names than companies,
> hence
>> the index should look like companyID, LastName, Firstname.
> So, if you go from most restrictive to least restrictive shouldn't the
> index
> be in the exact opposite order? (e.g. FirstName, LastName, CompanyID)
>> I would use one
>> index but it really depends. If most of your queries are like this
>> select * from tablename where companyid=1 and lastname =smith and
>> firstname=don the index should be on companyid, lastname and then first
>> name,
> Most of my queries are probably more like this
> select * from tablename where companyID = 1 order by lastname, firstname
>> Use a clustered index if you are doing a scan ie select * from tablename
>> where companyid>100, otherwise if you are only returning a few values use
> a
>> non clustered index.
> The companyID will always be just one value and not a range. With that
> said,
> maybe the LastName, FirstName should be the clustered choice with a
> non-clustered index for companyID?
> Thanks again for your help.
>|||Great answer Hugo, better than mine.
--
Hilary Cotter
Director of Text Mining and Database Strategy
RelevantNOISE.Com - Dedicated to mining blogs for business intelligence.
This posting is my own and doesn't necessarily represent RelevantNoise's
positions, strategies or opinions.
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Looking for a FAQ on Indexing Services/SQL FTS
http://www.indexserverfaq.com
"Hugo Kornelis" <hugo@.perFact.REMOVETHIS.info.INVALID> wrote in message
news:fj39g258fjaagokp4k9ci2r2flbqkpindb@.4ax.com...
> On Sun, 10 Sep 2006 10:58:40 -0500, Don Miller wrote:
>>After doing some reading, I'd like some expert opinions on choosing
>>indexes
>>for several scenarios.
> Hi Don,
> Here are mine. They are the diametrically opposite of Hilary's opinions,
> just to confuse you <eg>
>>1) One book said that you should almost index foreign keys in a table
>>since
>>lookups are more inefficient without them. I have tables with up to ten
>>FKs
>>used mostly for lookups from/joins with the PK table (e.g. marital status,
>>education level, etc.). Each of these PK lookup tables only have 3-10
>>possible values. However, pulling info from these PKs to display the
>>linked
>>items is a frequent event and many times a day a massive report
>>effectively
>>denormalizes everything for any individual customer.
>>Generally, is it worth the overhead to index foreign keys in one table for
>>primary key tables that have a handful of values?
> In cases like this, with the referred table holding marital status,
> education level, etc, indexes on the foreign key columns are often not
> needed. Though it depends on the nature of your queries. If you often
> query for female university level people or similar, indexes on those
> columns *MIGHT* get used. But for most queries, I expect SQL Server to
> filter rows based on other (more restrictive) criteria in the SELECT,
> then use bookmark lookup or a hash join to find the english name for the
> gender code, marital status code and education level code.
> Indexes on foreign key columns are mainly used to check the constraint
> on changes in the referenced table (which, in the case of marital status
> and education level, should be extremely rare - the contents of those
> tables are alomst constant) or when a very efficient filter can be
> applied to the referenced table (which is often the case between
> referencing table that hold non-constant data, such as orders and order
> details, or orders and customers).
>>2) If I have a web application for numerous companies that each have their
>>own customers, and when the folks from one company are using the
>>application
>>they only see their customers one at a time or an alphabetical list (a
>>pretty common scenario I would think), what is the best way to index
>>CompanyID (a FK to a Company PK table), CustLastName, CustFirstName?
> For queries like that, a clustered index no (CompanyID, CustLastName,
> CustFirstName) is best. The engine can use the index structure to find
> the first matching row in an instant; after that, it can navigate the
> logical order of the data in the clustered index to find all rows for
> the same company, and they'll already be in the order required. (It
> might help to include CompanyID as the first column in the ORDER BY
> clause.)
> Note that, contrary to popular belief, more or less restrictive should
> NOT be the first consideration for the order of columns in an index. You
> should start with hhow the columns are used; restrictiveness comes only
> second. If most of your searches are based on last name only, then last
> name should be the first column in the index, whether restrictive or
> not. If most searches are based on all three columns, then the order
> doesn't matter for those searches (though statistics will be slightly
> better if the most restrictive column is first). If all kinds of
> searches are mixed, then you should have the most restrictive column as
> the first in the index - and you might consider addition indexes for
> searches that can't use the index.
>>Is it better to have three distinct indexes? Which one should be the
>>optimal
>>for a clustered index? (I would think CompanyID since it is used for
>>almost
>>every query except for individual customers which are already indexed by
>>being a PK as CustomerID)
> I don't think three seperate indexes is a good idea. That might work if
> you often search on first name only, often search on last name only, and
> often search on CompanyID only. For searches on two or all three
> columns, SQL Server *can* use operations that use all three tables, then
> combine the intermediate results from those index searches - but the
> overhead of that is quite costly, so it'll very often just use one index
> to narrow down the search a bit, then search the rest by accessing all
> rows and checking the values.
> If you do use three indexes, than I think that CompanyID might indeed be
> the best choice, but I'd try different options to make sure. Of course,
> this also depends on the nature of other queries - above, you outlines
> one typical query, but iff there are others as well, you should include
> them in your analysis.
> And I agree that searches for individual customers would benefit from an
> index on CustomerID; since this is your key, the index shoould already
> exist. If you've used default options, it's the clustered index - I
> suggest that yoou change it to a nonclustered index, so that you can
> have (CompanyID, CustLastName, CustFirstName) as clustered index. The
> search for an individual customer results in just a single bookmark
> lookup, which is quite inexpensive. It's the searches for a range of
> rows where repeated bookmark lookups get expensive.
>>Or, should all of these be rolled into one composite index? If these are
>>rolled into a composite index, is there any value at all for still having
>>distinct indexes for these three columns? Would you still need an index
>>for
>>the company FK join to the PK Company table, e.g. to display the company
>>name?
> Some situations might benefit from additional indexes on the single
> columns (especially on the columns that are NOT first in the composite
> index).
> Finding company name based on CompanyID will in almost all cases require
> an index on the CompanyID column in the Companies table - which should
> be there already if you didn;t forget the primary key constraint.
>>Even though the CompanyID is not as selective as the combination of first
>>name and last name, I would think a clustered index of CompanyID,
>>CustLastName, CustFirstName would do the trick without any other indices.
>>But maybe a separate index for CompanyID (for company information
>>joins)?
> With that clustered index, a seperate index on only CompanyID would only
> give you some benefit in rare cases where the query is covered by this
> index - the benefit will probably not outweigh the cost of maintaining
> an additional index.
> --
> Hugo Kornelis, SQL Server MVP|||Hi Greg!
I have been putting together a presentation on indexing fundamentals for
some of the code camps. In some tests I ran it seems to me that clustered
indexes were better for scans, however I will have to try to repeat this to
verify it. I look forward to your research.
I'll be posting something in the private group soon which I have discovered
which I think it pretty interesting.
--
Hilary Cotter
Director of Text Mining and Database Strategy
RelevantNOISE.Com - Dedicated to mining blogs for business intelligence.
This posting is my own and doesn't necessarily represent RelevantNoise's
positions, strategies or opinions.
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Looking for a FAQ on Indexing Services/SQL FTS
http://www.indexserverfaq.com
"Greg Linwood" <g_linwood@.hotmail.com> wrote in message
news:OHZdTlS1GHA.1300@.TK2MSFTNGP05.phx.gbl...
> Hi Hilary
> Why is a clustered index better for a scan? Aren't all indexes sorted &
> therefore equally beneficial for scans? Non-clustered actually indexes
> more efficient for scans due to their higher page / row storage density..
> The only thing a clustered index can do better than a non-clustered index
> is cover the SELECT *, as it contains all columns, which definitely makes
> your advice right in this case, but I think your rationale isn't clear.
> I'm starting a series of short articles, intended to debunk the many myths
> about clustered indexes on my blog, including the classic "clustered
> indexes are better for range scans". I started this series a couple of
> days ago, covering the bookmark lookup problem but I'll cover this
> specific issue soon (it's definitely bogus):
> http://blogs.sqlserver.org.au/blogs/greg_linwood/archive/2006/09/10/363.aspx
> Regards,
> Greg Linwood
> SQL Server MVP
> "Hilary Cotter" <hilary.cotter@.gmail.com> wrote in message
> news:OUziSWQ1GHA.1256@.TK2MSFTNGP04.phx.gbl...
>> 1) yes, otherwise you will end up doing table scans. With the indexes in
>> place you will scan the index which is much more efficient.
>> 2) yes, always go from most restrictive to least restrict. You probably
>> have more first names, than last names and more last names than
>> companies, hence the index should look like companyID, LastName,
>> Firstname. I would use one index but it really depends. If most of your
>> queries are like this
>> select * from tablename where companyid=1 and lastname =smith and
>> firstname=don the index should be on companyid, lastname and then first
>> name, however if you query on lastnames or firstnames you should have an
>> index on each of these columns as well.
>> Use a clustered index if you are doing a scan ie select * from tablename
>> where companyid>100, otherwise if you are only returning a few values use
>> a non clustered index.
>> HTH
>> --
>> Hilary Cotter
>> Director of Text Mining and Database Strategy
>> RelevantNOISE.Com - Dedicated to mining blogs for business intelligence.
>> This posting is my own and doesn't necessarily represent RelevantNoise's
>> positions, strategies or opinions.
>> Looking for a SQL Server replication book?
>> http://www.nwsu.com/0974973602.html
>> Looking for a FAQ on Indexing Services/SQL FTS
>> http://www.indexserverfaq.com
>>
>> "Don Miller" <nospam@.nospam.com> wrote in message
>> news:Obu59EP1GHA.324@.TK2MSFTNGP05.phx.gbl...
>> After doing some reading, I'd like some expert opinions on choosing
>> indexes
>> for several scenarios.
>> 1) One book said that you should almost index foreign keys in a table
>> since
>> lookups are more inefficient without them. I have tables with up to ten
>> FKs
>> used mostly for lookups from/joins with the PK table (e.g. marital
>> status,
>> education level, etc.). Each of these PK lookup tables only have 3-10
>> possible values. However, pulling info from these PKs to display the
>> linked
>> items is a frequent event and many times a day a massive report
>> effectively
>> denormalizes everything for any individual customer.
>> Generally, is it worth the overhead to index foreign keys in one table
>> for
>> primary key tables that have a handful of values?
>> 2) If I have a web application for numerous companies that each have
>> their
>> own customers, and when the folks from one company are using the
>> application
>> they only see their customers one at a time or an alphabetical list (a
>> pretty common scenario I would think), what is the best way to index
>> CompanyID (a FK to a Company PK table), CustLastName, CustFirstName?
>> Is it better to have three distinct indexes? Which one should be the
>> optimal
>> for a clustered index? (I would think CompanyID since it is used for
>> almost
>> every query except for individual customers which are already indexed by
>> being a PK as CustomerID)
>> Or, should all of these be rolled into one composite index? If these are
>> rolled into a composite index, is there any value at all for still
>> having
>> distinct indexes for these three columns? Would you still need an index
>> for
>> the company FK join to the PK Company table, e.g. to display the company
>> name?
>> Even though the CompanyID is not as selective as the combination of
>> first
>> name and last name, I would think a clustered index of CompanyID,
>> CustLastName, CustFirstName would do the trick without any other
>> indices.
>> But maybe a separate index for CompanyID (for company information
>> joins)?
>> Thanks for any tips.
>>
>>
>|||"Hugo Kornelis" <hugo@.perFact.REMOVETHIS.info.INVALID> wrote in message
news:fj39g258fjaagokp4k9ci2r2flbqkpindb@.4ax.com...
> For queries like that, a clustered index no (CompanyID, CustLastName,
> CustFirstName) is best. The engine can use the index structure to find
> the first matching row in an instant; after that, it can navigate the
> logical order of the data in the clustered index to find all rows for
> the same company, and they'll already be in the order required. (It
> might help to include CompanyID as the first column in the ORDER BY
> clause.)
Actually, I tried to simplify things a little. Besides a company ID, there
are multiple regions within that company. I tried a clustered composite
index using companyID, regionID, lastname, firstname
Just looking at execution plans, I found that if I have a query like
select * from companies where companyID = ' and regionID = ' order by
lastname, firstname, or (as you suggested)
select * from companies where companyID = ' order by regionID, lastname,
firstname
there is one clustered index seek, but if I drop the regionID in the where
or order by clause, the execution plan includes a sort step in addition to
the index seek.
Hmmm. Didn't know that including *somewhere* the columns in a clustered
composite index would eliminate execution steps. Thanks for the
parenthetical.

Choosing Indexes

After doing some reading, I'd like some expert opinions on choosing indexes
for several scenarios.
1) One book said that you should almost index foreign keys in a table since
lookups are more inefficient without them. I have tables with up to ten FKs
used mostly for lookups from/joins with the PK table (e.g. marital status,
education level, etc.). Each of these PK lookup tables only have 3-10
possible values. However, pulling info from these PKs to display the linked
items is a frequent event and many times a day a massive report effectively
denormalizes everything for any individual customer.
Generally, is it worth the overhead to index foreign keys in one table for
primary key tables that have a handful of values?
2) If I have a web application for numerous companies that each have their
own customers, and when the folks from one company are using the application
they only see their customers one at a time or an alphabetical list (a
pretty common scenario I would think), what is the best way to index
CompanyID (a FK to a Company PK table), CustLastName, CustFirstName?
Is it better to have three distinct indexes? Which one should be the optimal
for a clustered index? (I would think CompanyID since it is used for almost
every query except for individual customers which are already indexed by
being a PK as CustomerID)
Or, should all of these be rolled into one composite index? If these are
rolled into a composite index, is there any value at all for still having
distinct indexes for these three columns? Would you still need an index for
the company FK join to the PK Company table, e.g. to display the company
name?
Even though the CompanyID is not as selective as the combination of first
name and last name, I would think a clustered index of CompanyID,
CustLastName, CustFirstName would do the trick without any other indices.
But maybe a separate index for CompanyID (for company information joins)?
Thanks for any tips.1) yes, otherwise you will end up doing table scans. With the indexes in
place you will scan the index which is much more efficient.
2) yes, always go from most restrictive to least restrict. You probably have
more first names, than last names and more last names than companies, hence
the index should look like companyID, LastName, Firstname. I would use one
index but it really depends. If most of your queries are like this
select * from tablename where companyid=1 and lastname =smith and
firstname=don the index should be on companyid, lastname and then first
name, however if you query on lastnames or firstnames you should have an
index on each of these columns as well.
Use a clustered index if you are doing a scan ie select * from tablename
where companyid>100, otherwise if you are only returning a few values use a
non clustered index.
HTH
Hilary Cotter
Director of Text Mining and Database Strategy
RelevantNOISE.Com - Dedicated to mining blogs for business intelligence.
This posting is my own and doesn't necessarily represent RelevantNoise's
positions, strategies or opinions.
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Looking for a FAQ on Indexing Services/SQL FTS
http://www.indexserverfaq.com
"Don Miller" <nospam@.nospam.com> wrote in message
news:Obu59EP1GHA.324@.TK2MSFTNGP05.phx.gbl...
> After doing some reading, I'd like some expert opinions on choosing
> indexes
> for several scenarios.
> 1) One book said that you should almost index foreign keys in a table
> since
> lookups are more inefficient without them. I have tables with up to ten
> FKs
> used mostly for lookups from/joins with the PK table (e.g. marital status,
> education level, etc.). Each of these PK lookup tables only have 3-10
> possible values. However, pulling info from these PKs to display the
> linked
> items is a frequent event and many times a day a massive report
> effectively
> denormalizes everything for any individual customer.
> Generally, is it worth the overhead to index foreign keys in one table for
> primary key tables that have a handful of values?
> 2) If I have a web application for numerous companies that each have their
> own customers, and when the folks from one company are using the
> application
> they only see their customers one at a time or an alphabetical list (a
> pretty common scenario I would think), what is the best way to index
> CompanyID (a FK to a Company PK table), CustLastName, CustFirstName?
> Is it better to have three distinct indexes? Which one should be the
> optimal
> for a clustered index? (I would think CompanyID since it is used for
> almost
> every query except for individual customers which are already indexed by
> being a PK as CustomerID)
> Or, should all of these be rolled into one composite index? If these are
> rolled into a composite index, is there any value at all for still having
> distinct indexes for these three columns? Would you still need an index
> for
> the company FK join to the PK Company table, e.g. to display the company
> name?
> Even though the CompanyID is not as selective as the combination of first
> name and last name, I would think a clustered index of CompanyID,
> CustLastName, CustFirstName would do the trick without any other indices.
> But maybe a separate index for CompanyID (for company information
> joins)?
> Thanks for any tips.
>|||Thanks for the advice, but I'm not sure if I understand all of your answers.

> 1) yes, otherwise you will end up doing table scans. With the indexes in
> place you will scan the index which is much more efficient.
Even faster than a table scan of only 5-10 rows total?

> 2) yes, always go from most restrictive to least restrict. You probably
have
> more first names, than last names and more last names than companies,
hence
> the index should look like companyID, LastName, Firstname.
So, if you go from most restrictive to least restrictive shouldn't the index
be in the exact opposite order? (e.g. FirstName, LastName, CompanyID)

> I would use one
> index but it really depends. If most of your queries are like this
> select * from tablename where companyid=1 and lastname =smith and
> firstname=don the index should be on companyid, lastname and then first
> name,
Most of my queries are probably more like this
select * from tablename where companyID = 1 order by lastname, firstname

> Use a clustered index if you are doing a scan ie select * from tablename
> where companyid>100, otherwise if you are only returning a few values use
a
> non clustered index.
The companyID will always be just one value and not a range. With that said,
maybe the LastName, FirstName should be the clustered choice with a
non-clustered index for companyID?
Thanks again for your help.|||Hi Hilary
Why is a clustered index better for a scan? Aren't all indexes sorted &
therefore equally beneficial for scans? Non-clustered actually indexes more
efficient for scans due to their higher page / row storage density..
The only thing a clustered index can do better than a non-clustered index is
cover the SELECT *, as it contains all columns, which definitely makes your
advice right in this case, but I think your rationale isn't clear.
I'm starting a series of short articles, intended to debunk the many myths
about clustered indexes on my blog, including the classic "clustered indexes
are better for range scans". I started this series a couple of days ago,
covering the bookmark lookup problem but I'll cover this specific issue soon
(it's definitely bogus):
http://blogs.sqlserver.org.au/blogs.../09/10/363.aspx
Regards,
Greg Linwood
SQL Server MVP
"Hilary Cotter" <hilary.cotter@.gmail.com> wrote in message
news:OUziSWQ1GHA.1256@.TK2MSFTNGP04.phx.gbl...
> 1) yes, otherwise you will end up doing table scans. With the indexes in
> place you will scan the index which is much more efficient.
> 2) yes, always go from most restrictive to least restrict. You probably
> have more first names, than last names and more last names than companies,
> hence the index should look like companyID, LastName, Firstname. I would
> use one index but it really depends. If most of your queries are like this
> select * from tablename where companyid=1 and lastname =smith and
> firstname=don the index should be on companyid, lastname and then first
> name, however if you query on lastnames or firstnames you should have an
> index on each of these columns as well.
> Use a clustered index if you are doing a scan ie select * from tablename
> where companyid>100, otherwise if you are only returning a few values use
> a non clustered index.
> HTH
> --
> Hilary Cotter
> Director of Text Mining and Database Strategy
> RelevantNOISE.Com - Dedicated to mining blogs for business intelligence.
> This posting is my own and doesn't necessarily represent RelevantNoise's
> positions, strategies or opinions.
> Looking for a SQL Server replication book?
> http://www.nwsu.com/0974973602.html
> Looking for a FAQ on Indexing Services/SQL FTS
> http://www.indexserverfaq.com
>
> "Don Miller" <nospam@.nospam.com> wrote in message
> news:Obu59EP1GHA.324@.TK2MSFTNGP05.phx.gbl...
>|||On Sun, 10 Sep 2006 10:58:40 -0500, Don Miller wrote:

>After doing some reading, I'd like some expert opinions on choosing indexes
>for several scenarios.
Hi Don,
Here are mine. They are the diametrically opposite of Hilary's opinions,
just to confuse you <eg>

>1) One book said that you should almost index foreign keys in a table since
>lookups are more inefficient without them. I have tables with up to ten FKs
>used mostly for lookups from/joins with the PK table (e.g. marital status,
>education level, etc.). Each of these PK lookup tables only have 3-10
>possible values. However, pulling info from these PKs to display the linked
>items is a frequent event and many times a day a massive report effectively
>denormalizes everything for any individual customer.
>Generally, is it worth the overhead to index foreign keys in one table for
>primary key tables that have a handful of values?
In cases like this, with the referred table holding marital status,
education level, etc, indexes on the foreign key columns are often not
needed. Though it depends on the nature of your queries. If you often
query for female university level people or similar, indexes on those
columns *MIGHT* get used. But for most queries, I expect SQL Server to
filter rows based on other (more restrictive) criteria in the SELECT,
then use bookmark lookup or a hash join to find the english name for the
gender code, marital status code and education level code.
Indexes on foreign key columns are mainly used to check the constraint
on changes in the referenced table (which, in the case of marital status
and education level, should be extremely rare - the contents of those
tables are alomst constant) or when a very efficient filter can be
applied to the referenced table (which is often the case between
referencing table that hold non-constant data, such as orders and order
details, or orders and customers).

>2) If I have a web application for numerous companies that each have their
>own customers, and when the folks from one company are using the applicatio
n
>they only see their customers one at a time or an alphabetical list (a
>pretty common scenario I would think), what is the best way to index
>CompanyID (a FK to a Company PK table), CustLastName, CustFirstName?
For queries like that, a clustered index no (CompanyID, CustLastName,
CustFirstName) is best. The engine can use the index structure to find
the first matching row in an instant; after that, it can navigate the
logical order of the data in the clustered index to find all rows for
the same company, and they'll already be in the order required. (It
might help to include CompanyID as the first column in the ORDER BY
clause.)
Note that, contrary to popular belief, more or less restrictive should
NOT be the first consideration for the order of columns in an index. You
should start with hhow the columns are used; restrictiveness comes only
second. If most of your searches are based on last name only, then last
name should be the first column in the index, whether restrictive or
not. If most searches are based on all three columns, then the order
doesn't matter for those searches (though statistics will be slightly
better if the most restrictive column is first). If all kinds of
searches are mixed, then you should have the most restrictive column as
the first in the index - and you might consider addition indexes for
searches that can't use the index.

>Is it better to have three distinct indexes? Which one should be the optima
l
>for a clustered index? (I would think CompanyID since it is used for almost
>every query except for individual customers which are already indexed by
>being a PK as CustomerID)
I don't think three seperate indexes is a good idea. That might work if
you often search on first name only, often search on last name only, and
often search on CompanyID only. For searches on two or all three
columns, SQL Server *can* use operations that use all three tables, then
combine the intermediate results from those index searches - but the
overhead of that is quite costly, so it'll very often just use one index
to narrow down the search a bit, then search the rest by accessing all
rows and checking the values.
If you do use three indexes, than I think that CompanyID might indeed be
the best choice, but I'd try different options to make sure. Of course,
this also depends on the nature of other queries - above, you outlines
one typical query, but iff there are others as well, you should include
them in your analysis.
And I agree that searches for individual customers would benefit from an
index on CustomerID; since this is your key, the index shoould already
exist. If you've used default options, it's the clustered index - I
suggest that yoou change it to a nonclustered index, so that you can
have (CompanyID, CustLastName, CustFirstName) as clustered index. The
search for an individual customer results in just a single bookmark
lookup, which is quite inexpensive. It's the searches for a range of
rows where repeated bookmark lookups get expensive.

>Or, should all of these be rolled into one composite index? If these are
>rolled into a composite index, is there any value at all for still having
>distinct indexes for these three columns? Would you still need an index for
>the company FK join to the PK Company table, e.g. to display the company
>name?
Some situations might benefit from additional indexes on the single
columns (especially on the columns that are NOT first in the composite
index).
Finding company name based on CompanyID will in almost all cases require
an index on the CompanyID column in the Companies table - which should
be there already if you didn;t forget the primary key constraint.

>Even though the CompanyID is not as selective as the combination of first
>name and last name, I would think a clustered index of CompanyID,
>CustLastName, CustFirstName would do the trick without any other indices.
>But maybe a separate index for CompanyID (for company information joins)?
With that clustered index, a seperate index on only CompanyID would only
give you some benefit in rare cases where the query is covered by this
index - the benefit will probably not outweigh the cost of maintaining
an additional index.
Hugo Kornelis, SQL Server MVP|||1) well probably not. But for larger tables indexes are faster than table
scans.
2) Well when I think most restrictive I think of a value which returns the
fewest results. So as there are fewer company id's than Smiths and even
fewer company id's than Johns, I would argue that it would go some
companyID, LastName and then FirstName.
So consider John Smith where there are 200 john smiths per company id and
there are 20 companies. If you search on FirstName, LastName, CompanyID you
would return 200*20 rows to the filtering condition which filters out
company id's. Then 200 are returned. If you go Company ID, then Names, 200
rows are returned to the filtering condition and then 200 remain in the
filter.
Make sense?
Hilary Cotter
Director of Text Mining and Database Strategy
RelevantNOISE.Com - Dedicated to mining blogs for business intelligence.
This posting is my own and doesn't necessarily represent RelevantNoise's
positions, strategies or opinions.
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Looking for a FAQ on Indexing Services/SQL FTS
http://www.indexserverfaq.com
"Don Miller" <nospam@.nospam.com> wrote in message
news:uXL6NgQ1GHA.4648@.TK2MSFTNGP04.phx.gbl...
> Thanks for the advice, but I'm not sure if I understand all of your
> answers.
>
> Even faster than a table scan of only 5-10 rows total?
>
> have
> hence
> So, if you go from most restrictive to least restrictive shouldn't the
> index
> be in the exact opposite order? (e.g. FirstName, LastName, CompanyID)
>
> Most of my queries are probably more like this
> select * from tablename where companyID = 1 order by lastname, firstname
>
> a
> The companyID will always be just one value and not a range. With that
> said,
> maybe the LastName, FirstName should be the clustered choice with a
> non-clustered index for companyID?
> Thanks again for your help.
>|||Great answer Hugo, better than mine.
Hilary Cotter
Director of Text Mining and Database Strategy
RelevantNOISE.Com - Dedicated to mining blogs for business intelligence.
This posting is my own and doesn't necessarily represent RelevantNoise's
positions, strategies or opinions.
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Looking for a FAQ on Indexing Services/SQL FTS
http://www.indexserverfaq.com
"Hugo Kornelis" <hugo@.perFact.REMOVETHIS.info.INVALID> wrote in message
news:fj39g258fjaagokp4k9ci2r2flbqkpindb@.
4ax.com...
> On Sun, 10 Sep 2006 10:58:40 -0500, Don Miller wrote:
>
> Hi Don,
> Here are mine. They are the diametrically opposite of Hilary's opinions,
> just to confuse you <eg>
>
> In cases like this, with the referred table holding marital status,
> education level, etc, indexes on the foreign key columns are often not
> needed. Though it depends on the nature of your queries. If you often
> query for female university level people or similar, indexes on those
> columns *MIGHT* get used. But for most queries, I expect SQL Server to
> filter rows based on other (more restrictive) criteria in the SELECT,
> then use bookmark lookup or a hash join to find the english name for the
> gender code, marital status code and education level code.
> Indexes on foreign key columns are mainly used to check the constraint
> on changes in the referenced table (which, in the case of marital status
> and education level, should be extremely rare - the contents of those
> tables are alomst constant) or when a very efficient filter can be
> applied to the referenced table (which is often the case between
> referencing table that hold non-constant data, such as orders and order
> details, or orders and customers).
>
> For queries like that, a clustered index no (CompanyID, CustLastName,
> CustFirstName) is best. The engine can use the index structure to find
> the first matching row in an instant; after that, it can navigate the
> logical order of the data in the clustered index to find all rows for
> the same company, and they'll already be in the order required. (It
> might help to include CompanyID as the first column in the ORDER BY
> clause.)
> Note that, contrary to popular belief, more or less restrictive should
> NOT be the first consideration for the order of columns in an index. You
> should start with hhow the columns are used; restrictiveness comes only
> second. If most of your searches are based on last name only, then last
> name should be the first column in the index, whether restrictive or
> not. If most searches are based on all three columns, then the order
> doesn't matter for those searches (though statistics will be slightly
> better if the most restrictive column is first). If all kinds of
> searches are mixed, then you should have the most restrictive column as
> the first in the index - and you might consider addition indexes for
> searches that can't use the index.
>
> I don't think three seperate indexes is a good idea. That might work if
> you often search on first name only, often search on last name only, and
> often search on CompanyID only. For searches on two or all three
> columns, SQL Server *can* use operations that use all three tables, then
> combine the intermediate results from those index searches - but the
> overhead of that is quite costly, so it'll very often just use one index
> to narrow down the search a bit, then search the rest by accessing all
> rows and checking the values.
> If you do use three indexes, than I think that CompanyID might indeed be
> the best choice, but I'd try different options to make sure. Of course,
> this also depends on the nature of other queries - above, you outlines
> one typical query, but iff there are others as well, you should include
> them in your analysis.
> And I agree that searches for individual customers would benefit from an
> index on CustomerID; since this is your key, the index shoould already
> exist. If you've used default options, it's the clustered index - I
> suggest that yoou change it to a nonclustered index, so that you can
> have (CompanyID, CustLastName, CustFirstName) as clustered index. The
> search for an individual customer results in just a single bookmark
> lookup, which is quite inexpensive. It's the searches for a range of
> rows where repeated bookmark lookups get expensive.
>
> Some situations might benefit from additional indexes on the single
> columns (especially on the columns that are NOT first in the composite
> index).
> Finding company name based on CompanyID will in almost all cases require
> an index on the CompanyID column in the Companies table - which should
> be there already if you didn;t forget the primary key constraint.
>
> With that clustered index, a seperate index on only CompanyID would only
> give you some benefit in rare cases where the query is covered by this
> index - the benefit will probably not outweigh the cost of maintaining
> an additional index.
> --
> Hugo Kornelis, SQL Server MVP|||Hi Greg!
I have been putting together a presentation on indexing fundamentals for
some of the code camps. In some tests I ran it seems to me that clustered
indexes were better for scans, however I will have to try to repeat this to
verify it. I look forward to your research.
I'll be posting something in the private group soon which I have discovered
which I think it pretty interesting.
Hilary Cotter
Director of Text Mining and Database Strategy
RelevantNOISE.Com - Dedicated to mining blogs for business intelligence.
This posting is my own and doesn't necessarily represent RelevantNoise's
positions, strategies or opinions.
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Looking for a FAQ on Indexing Services/SQL FTS
http://www.indexserverfaq.com
"Greg Linwood" <g_linwood@.hotmail.com> wrote in message
news:OHZdTlS1GHA.1300@.TK2MSFTNGP05.phx.gbl...
> Hi Hilary
> Why is a clustered index better for a scan? Aren't all indexes sorted &
> therefore equally beneficial for scans? Non-clustered actually indexes
> more efficient for scans due to their higher page / row storage density..
> The only thing a clustered index can do better than a non-clustered index
> is cover the SELECT *, as it contains all columns, which definitely makes
> your advice right in this case, but I think your rationale isn't clear.
> I'm starting a series of short articles, intended to debunk the many myths
> about clustered indexes on my blog, including the classic "clustered
> indexes are better for range scans". I started this series a couple of
> days ago, covering the bookmark lookup problem but I'll cover this
> specific issue soon (it's definitely bogus):
> [url]http://blogs.sqlserver.org.au/blogs/greg_linwood/archive/2006/09/10/363.aspx[/ur
l]
> Regards,
> Greg Linwood
> SQL Server MVP
> "Hilary Cotter" <hilary.cotter@.gmail.com> wrote in message
> news:OUziSWQ1GHA.1256@.TK2MSFTNGP04.phx.gbl...
>|||"Hugo Kornelis" <hugo@.perFact.REMOVETHIS.info.INVALID> wrote in message
news:fj39g258fjaagokp4k9ci2r2flbqkpindb@.
4ax.com...

> For queries like that, a clustered index no (CompanyID, CustLastName,
> CustFirstName) is best. The engine can use the index structure to find
> the first matching row in an instant; after that, it can navigate the
> logical order of the data in the clustered index to find all rows for
> the same company, and they'll already be in the order required. (It
> might help to include CompanyID as the first column in the ORDER BY
> clause.)
Actually, I tried to simplify things a little. Besides a company ID, there
are multiple regions within that company. I tried a clustered composite
index using companyID, regionID, lastname, firstname
Just looking at execution plans, I found that if I have a query like
select * from companies where companyID = ' and regionID = ' order by
lastname, firstname, or (as you suggested)
select * from companies where companyID = ' order by regionID, lastname,
firstname
there is one clustered index seek, but if I drop the regionID in the where
or order by clause, the execution plan includes a sort step in addition to
the index seek.
Hmmm. Didn't know that including *somewhere* the columns in a clustered
composite index would eliminate execution steps. Thanks for the
parenthetical.

Friday, February 10, 2012

Check the sql server service account

Hello!

I would need to check the name of the sql server service account from inside TSQL.

I had one idea about reading from the sysprocesses system table,
but that only gives me information about the SQL Server Agent service account.

Are there other ways?

(It has to work for both SQL Server 2000 and SQL Server 2005.)

Best regards

Ola Hallengren

There is an undocmented approach using 'registry key reading' in SQL Server 2000 version:

xp_regread @.rootkey='HKEY_LOCAL_MACHINE',
@.key='SYSTEM\ControlSet001\Services\SQLServerAgent',
@.value_name='ObjectName'

I'm working onSQL 2005 and will post here once it is successful.