﻿<?xml version='1.0' encoding='UTF-8'?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>SQLServerCentral / Article Discussions / Article Discussions by Author / Discuss content posted by Gail Shaw  / Introduction to Indexes: Part 2 – The clustered index / Latest Posts</title><generator>InstantForum.NET v2.9.0</generator><description>SQLServerCentral</description><link>http://www.sqlservercentral.com/Forums/</link><webMaster>notifications@sqlservercentral.com</webMaster><lastBuildDate>Fri, 17 May 2013 23:26:37 GMT</lastBuildDate><ttl>20</ttl><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Sorry for dragging the discussion. I setup a small test below.[code="sql"]CREATE TABLE DUMMY_TABLE(	ID_COL INT,	DESC_COL CHAR(8000),)GOINSERT INTO DUMMY_TABLE VALUES(1, REPLICATE('X',8000)),(2, REPLICATE('X',8000)),(3, REPLICATE('X',8000)),(4, REPLICATE('X',8000)),(5, REPLICATE('X',8000)),(6, REPLICATE('X',8000)),(7, REPLICATE('X',8000)),(8, REPLICATE('X',8000)),(9, REPLICATE('X',8000))GOCREATE CLUSTERED INDEX IX_DUMMY_TABLE ON DBO.DUMMY_TABLE	(	ID_COL	)GOSET STATISTICS IO ON-- Query 1 SELECT * FROM DUMMY_TABLE WHERE ID_COL &amp;gt; 1 --AND ID_COL &amp;lt; 9-------------------------- Query 2 SELECT * FROM DUMMY_TABLE -------------------------- Query 3 SELECT * FROM DUMMY_TABLE WHERE ID_COL = 1 --AND ID_COL &amp;lt; 9GODROP TABLE DUMMY_TABLESET STATISTICS IO OFF [/code]Scott, you were right. Execution plans (actual/estimate) show SEEK operation for 1st &amp; 3rd queries. It’s quite surprising to me but I have to accept the fact, it’s SEEK operation.BUT when I see the IO statistics, I see no difference between first two queries. So the SEEK predicate on in first query is fake IMO.[code="plain"](9 row(s) affected)(8 row(s) affected)[b]Table 'DUMMY_TABLE'. Scan count 1, logical reads 11,[/b] physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.(9 row(s) affected)[b]Table 'DUMMY_TABLE'. Scan count 1, logical reads 11,[/b] physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.(1 row(s) affected)Table 'DUMMY_TABLE'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.[/code]</description><pubDate>Mon, 09 Jul 2012 11:28:43 GMT</pubDate><dc:creator>Dev</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Sure. We will do it together…[b]Scans vs. Seeks [/b][url]http://blogs.msdn.com/b/craigfr/archive/2006/06/26/647852.aspx[/url]</description><pubDate>Mon, 09 Jul 2012 10:44:58 GMT</pubDate><dc:creator>Dev</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]Dev (7/9/2012)[/b][hr][quote][b]ScottPletcher (7/9/2012)[/b][hr][quote][b]Dev (7/9/2012)[/b][b]‘select only a very small % of the total rows’ [/b]is applicable to Clustered Index as well for seek operation else it will scan the cluster.[/quote]False, of course.  If, for example, you have a table with two years' worth of data, 2010 and 2011, clustered on date, and you specify &amp;gt;= '20110101', SQL will read only the 2011 data.That is another main reason you should leverage the clus index as much as possible.[/quote]It’s just an optimization added to SCAN operation but it won’t be good anyways if the data is skewed and ‘&amp;gt;= 20110101’ returns 90% of rows.[/quote]Nope, sorry.  You need to review the difference between "scan" and "seek".</description><pubDate>Mon, 09 Jul 2012 10:29:35 GMT</pubDate><dc:creator>ScottPletcher</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]ScottPletcher (7/9/2012)[/b][hr][quote][b]Dev (7/9/2012)[/b][b]‘select only a very small % of the total rows’ [/b]is applicable to Clustered Index as well for seek operation else it will scan the cluster.[/quote]False, of course.  If, for example, you have a table with two years' worth of data, 2010 and 2011, clustered on date, and you specify &amp;gt;= '20110101', SQL will read only the 2011 data.That is another main reason you should leverage the clus index as much as possible.[/quote]It’s just an optimization added to SCAN operation but it won’t be good anyways if the data is skewed and ‘&amp;gt;= 20110101’ returns 90% of rows.</description><pubDate>Mon, 09 Jul 2012 10:17:13 GMT</pubDate><dc:creator>Dev</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]Dev (7/9/2012)[/b][b]‘select only a very small % of the total rows’ [/b]is applicable to Clustered Index as well for seek operation else it will scan the cluster.[/quote]False, of course.  If, for example, you have a table with two years' worth of data, 2010 and 2011, clustered on date, and you specify &amp;gt;= '20110101', SQL will read only the 2011 data.That is another main reason you should leverage the clus index as much as possible.</description><pubDate>Mon, 09 Jul 2012 10:04:27 GMT</pubDate><dc:creator>ScottPletcher</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Let me put this way; I have a table XYZ and an ID (Primary, Clustered Index). I typically don’t query on ID column but it’s used in many queries for joins. I typically search based on Description (Non-Clustered index).Now in this case, assume I don’t have Non-Clustered index in place and I query based on Description column, it will scan the cluster. Will it be a good plan? If I have Non-Clustered index (on description) in place, based on selectivity optimizer may pick the index. Isn’t it a good plan?In continuation to the same, if the query selects few non-key columns as well, I may include couple of columns (mostly queried) in it. If this index can satisfy 60-80% queries on that table I will consider it a good index.The major fact, we can have only one Clustered Index on a table (ignoring workaround with INCLUDE). [b]‘select only a very small % of the total rows’ [/b]is applicable to Clustered Index as well for seek operation else it will scan the cluster.</description><pubDate>Mon, 09 Jul 2012 09:57:09 GMT</pubDate><dc:creator>Dev</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>What does that have to do with the clustered index key, though? You certainly can't cover every possible query with the clustered index (unless you have an incredibly simple database), so you have to have nonclustered ones--and if you have them, then having the clustering key as small as possible (since it needs to be repeated in every NC index) is surely a good idea, which is pretty much what Gail said?</description><pubDate>Mon, 09 Jul 2012 09:23:52 GMT</pubDate><dc:creator>paul.knibbs</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]Dev (7/8/2012)[/b][hr]As a matter of fact, you can’t avoid the scans (table / index) in real life or practical scenarios but you can minimize those and that’s what Gail is trying to explain here.Every columns that you add to query as predicate may or may not be covering at the moment. It needs not to be covering especially in ad-hoc query environments it’s very common. If a query that executes rarely, I don’t see any reason to worry much on it unless an explicit weight / priority is assign to that query.Also, you would not like to include all the columns in non-clustered index just to make it covering. Would you?[/quote]Not at all.  That's why I clearly stated, the (vast) majority of the queries should be using the [u]clustered[/u] index to limit rows.What Gail stated is:[quote]clustered index to organise the table, nonclusters to support the queries.[/quote][quote]I make covering indexes for critical queries[/quote]If nonclus are to support the queries, they need to be:1) covering indexes  OR2) select only a [b]very small %[/b] of the total rowsSince you can't directly control #2, aren't you then [u]forced[/u] to make covering indexes?If the query restricts to a minimum range of rows based on the clustered index, I don't have to make any adjustments then even if they select/compare every column in the table.</description><pubDate>Mon, 09 Jul 2012 09:20:25 GMT</pubDate><dc:creator>ScottPletcher</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>As a matter of fact, you can’t avoid the scans (table / index) in real life or practical scenarios but you can minimize those and that’s what Gail is trying to explain here.Every columns that you add to query as predicate may or may not be covering at the moment. It needs not to be covering especially in ad-hoc query environments it’s very common. If a query that executes rarely, I don’t see any reason to worry much on it unless an explicit weight / priority is assign to that query.Also, you would not like to include all the columns in non-clustered index just to make it covering. Would you?</description><pubDate>Sun, 08 Jul 2012 02:59:36 GMT</pubDate><dc:creator>Dev</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]The most important performance aspect of a table is determining the correct clustered index.[/b]Absolutely, and what I want is one that is narrow - doesn't make nonclustered indexes larger than they need to be -, unique - doesn't require a uniquifier column - , unchanging - that isn't going to require that every nonclustered index on the table be updated when the clustering key value is changed - and ever-increasing - that isn't going to cause huge fragmentation due to inserts.[/quote]The same rote quote, and, yes, those are good general rules, but not enough by themselves.Please, those of you learning about clustered indexes, look beyond the no-thought approach.Instead, [b]consider the actual requirements of your specific table [u]before[/u] determining the clustered index key(s) for that table[/b].  You'll save yourself huge performance problems and the extra work required to re-index the table properly later.</description><pubDate>Fri, 06 Jul 2012 12:16:38 GMT</pubDate><dc:creator>ScottPletcher</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]ScottPletcher (7/6/2012)[/b][hr][quote][b]GilaMonster (7/6/2012)[/b][u]Every[/u] column added to a query invalidates the existing covering index and will revert back to a table scan.[/quote]Not necessarily a table scan. Maybe a seek + lookup, maybe index intersection, maybe an index scan. SQL has lots of options for indexes.How do you keep up with every single-column change to thousands of queries for thousands of databases and tens of thousands, or even millions, of tables, to keep all your non-clus indexes as truly covering?[/quote]I don't. I make covering indexes for critical queries, ensure that not-so-critical queries perform within requirements and make sure that new developments are correctly performance tested and that the developers have made any necessary index creations or modifications before the change are deployed to production.How do you keep up with changes to all the queries across thousands of databases and tens of thousands, or even millions tables to keep all your nonclustered indexes up to date and useful for the queries that don't use the clustered index, seeing as I have very seldom seen tables with one and only one access path? (and the cluster can only support one access path)[quote][b]The most important performance aspect of a table is determining the correct clustered index.[/b][/quote]Absolutely, and what I want is one that is narrow - doesn't make nonclustered indexes larger than they need to be -, unique - doesn't require a uniquifier column - , unchanging - that isn't going to require that every nonclustered index on the table be updated when the clustering key value is changed - and ever-increasing - that isn't going to cause huge fragmentation due to inserts.</description><pubDate>Fri, 06 Jul 2012 10:57:25 GMT</pubDate><dc:creator>GilaMonster</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]GilaMonster (7/6/2012)[/b]There's only one clustered index, multiple nonclustered indexes, clustered index to organise the table, nonclusters to support the queries.[/quote][u]Every[/u] column added to a query invalidates the existing covering index and will revert back to a table scan.How do you keep up with every single-column change to thousands of queries for thousands of databases and tens of thousands, or even millions, of tables, to keep all your non-clus indexes as truly covering?Just not possible, practical or worthwhile.  [b]The most important performance aspect of a table is determining the correct clustered index.[/b]</description><pubDate>Fri, 06 Jul 2012 10:49:44 GMT</pubDate><dc:creator>ScottPletcher</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]ScottPletcher (7/6/2012)[/b][hr][quote]An integer column defined as identity (a very good and popular choice for clustered index) is 4 bytes.[/quote]It's certainly popular, but most often [u]not[/u] good.  The no-thought identity as clustered key likely causes more performance problems than any other single thing.[/quote]We'll have to agree to disagree on that matter. I hold to the school of thought that the clustered index should first organise the data (narrow, unchanging, ever-increasing, unique). If it can also support queries that's a bonus.There's only one clustered index, multiple nonclustered indexes, clustered index to organise the table, nonclusters to support the queries.</description><pubDate>Fri, 06 Jul 2012 10:13:26 GMT</pubDate><dc:creator>GilaMonster</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote]An integer column defined as identity (a very good and popular choice for clustered index) is 4 bytes.[/quote]It's certainly popular, but most often [u]not[/u] good.  The no-thought identity as clustered key likely causes more performance problems than any other single thing.Most "guidelines" for the clus key affect mostly the INSERT of new rows, which is done only once.  Keep in mind that rows will typically be read dozens or hundreds of times after being INSERTed.  In fact, even very likely thousands of times if you force too many table scans by having the wrong clustered key.[b]Nonclustered indexes should not be thought of as the main way to access data.[/b]  You want the primary access to be through the clustered index.Often a (date) OR (parent_key, child_key) (such as order_number, item_number) makes a vastly better clustering key than identity.</description><pubDate>Fri, 06 Jul 2012 08:40:19 GMT</pubDate><dc:creator>ScottPletcher</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]GilaMonster (10/24/2011)[/b][hr][quote][b]ChrisM@Work (10/24/2011)[/b][hr]So if a table has 4.5 million rows and the Clustered Index Scan operator properties sheet displays "Actual number of rows 720939" for a query against that table, it's scanning [i]the whole table[/i] but only [i]returning[/i] 720,939 rows? [/quote]Quite likely, yes. There are some cases where a clustered index (or nonclustered index) scan can abort early, that's usually due to TOP or some constructs of Row_number.The Actual rows is always the rows returned, not the rows read, so if there's a predicate on that scan, it's the number of rows that qualified for the predicate, not the number read from the table.[quote]The sheet subtitle says "Scanning a clustered index, entirely or only a range".[/quote]A bit incorrect. A range scan (&amp;lt;clustered key&amp;gt; between @SomeValue and @SomeOtherValue) appears as a seek.[/quote]Awesome. Many thanks Gail.</description><pubDate>Wed, 26 Oct 2011 02:18:27 GMT</pubDate><dc:creator>ChrisM@Work</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]ChrisM@Work (10/24/2011)[/b][hr]So if a table has 4.5 million rows and the Clustered Index Scan operator properties sheet displays "Actual number of rows 720939" for a query against that table, it's scanning [i]the whole table[/i] but only [i]returning[/i] 720,939 rows? [/quote]Quite likely, yes. There are some cases where a clustered index (or nonclustered index) scan can abort early, that's usually due to TOP or some constructs of Row_number.The Actual rows is always the rows returned, not the rows read, so if there's a predicate on that scan, it's the number of rows that qualified for the predicate, not the number read from the table.[quote]The sheet subtitle says "Scanning a clustered index, entirely or only a range".[/quote]A bit incorrect. A range scan (&amp;lt;clustered key&amp;gt; between @SomeValue and @SomeOtherValue) appears as a seek.</description><pubDate>Mon, 24 Oct 2011 10:45:58 GMT</pubDate><dc:creator>GilaMonster</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>"A scan of the clustered index is equivalent to a table scan. It’s a read of all of the data pages in the table...This is a full scan of all the data pages, i.e. a table scan..."So if a table has 4.5 million rows and the Clustered Index Scan operator properties sheet displays "Actual number of rows 720939" for a query against that table, it's scanning [i]the whole table[/i] but only [i]returning[/i] 720,939 rows? The sheet subtitle says "Scanning a clustered index, entirely or only a range".</description><pubDate>Mon, 24 Oct 2011 10:09:17 GMT</pubDate><dc:creator>ChrisM@Work</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Sure, you can get index intersections. Doesn't mean you always will nor that they are the most optimal approachp.s. Yes, part 3 needs an edit in that area, but it did not say that SQL would never seek on all three and intersect.</description><pubDate>Thu, 27 Jan 2011 10:13:25 GMT</pubDate><dc:creator>GilaMonster</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>FYI, 3 columns with an index on each one separately produced and index intersection plan on my 2008, unlike what the article said! - this is in reference to part 3.</description><pubDate>Thu, 27 Jan 2011 10:10:06 GMT</pubDate><dc:creator>Rafael H</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>The clustered index is been updated. While you may not be updating the clustered index key, as I mentioned in the article "A clustered index is an index where the leaf level of the index contains the actual data rows of the table".Since the actual data rows are at the leaf of the clustered index, the cluster will be affected by all updates against that table. In essence, it is the table.</description><pubDate>Mon, 17 Jan 2011 22:56:53 GMT</pubDate><dc:creator>GilaMonster</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Hi Gail,When you're performing an update on a non-clustered index column on a table with clustered index (CI), the execution plan indicated that CI is being Updated.Do you know why this behaviour happens, and is CI is really being updated although you're not updating the CI column?Thanks,Simon</description><pubDate>Mon, 17 Jan 2011 19:57:47 GMT</pubDate><dc:creator>Simon-413722</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Excellent article Gail!  Very simple and easy to understand with the fundamentals that add up to a good understanding of the subject.These articles should be required reading for both newbies and old hands alike.Todd Fifield</description><pubDate>Fri, 14 Jan 2011 11:15:43 GMT</pubDate><dc:creator>tfifield</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Nice :cool:</description><pubDate>Fri, 14 Jan 2011 09:55:46 GMT</pubDate><dc:creator>hjohnson</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Thanks for writing this series, as apparent with all the responces, there is a lake of this knowledge in the development world. I was once like some of these respondees in my want to understand indexes and how they work.You did an excellent job of firing the minds of the SQL Server community. Especialy responding the all the questions.I realy like the covering index with include columns responce to the SQLGuru's wanting more than one clustered index. That was classic. :)Thanks and God Bless,ThomasTheSmilingDBA</description><pubDate>Fri, 14 Jan 2011 06:57:54 GMT</pubDate><dc:creator>Thomas LeBlanc</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>The guys who write SQL Server think of everything, it seems!</description><pubDate>Fri, 07 Jan 2011 02:52:51 GMT</pubDate><dc:creator>paul.knibbs</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>It would throw an error. Error 666, Severity 16The maximum system-generated unique value for a duplicate group was exceeded for index with partition ID &amp;lt;Partition ID&amp;gt;. Dropping and re-creating the index may resolve this; otherwise, use another clustering key.[url]http://robboek.com/2009/02/13/sql-server-uniqueifier-values-and-the-number-of-the-beast/[/url]</description><pubDate>Fri, 07 Jan 2011 02:36:50 GMT</pubDate><dc:creator>GilaMonster</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Out of sheer curiosity: you mention that a hidden 4-byte column is added to the clustered index key to make it unique in the event that it is not. Let's say we had a really, really badly designed clustered index where there were more than 2^32 rows with the same key--I realise this is vanishingly unlikely in the real world. What would actually happen? Would SQL report an error, and if so, what?</description><pubDate>Fri, 07 Jan 2011 02:29:51 GMT</pubDate><dc:creator>paul.knibbs</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>OK now I have a better idea of what you meant. The depth of the tree is obviously very important.You referred to the downsides of heaps, and I wasn't sure what those were, other than some data &amp; index fragmentation (which might be more or less cancelled out by cacheing). In a couple of cases in your 3-part article, heaps compared favorably to clustered DB's. However I did a search or two of this site, and came up with information that clarified it:http://www.sqlservercentral.com/blogs/aloha_dba/archive/2009/2/13/which-is-better-heaps-or-tables-with-clustered-indexes.aspxhttp://technet.microsoft.com/en-us/library/cc917672.aspxThanks for your information.</description><pubDate>Thu, 11 Mar 2010 15:23:06 GMT</pubDate><dc:creator>wodom</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>It won't be several unless you're dealing with many millions of pages in the index. The upper levels of indexes are very small in relation to the leaf level and are in general in cache all the time (they're hot, frequently used pages).To give you an idea, let's take a 1 million row table with rows 8000 bytes each (so 1 to a page) and a 100 byte clustered index key (which is a huge clustered index key). (ignoring row headers and the like for a rough calc)Leaf level = 1 000 000 pagesLevel 1 = 12 000 pagesLevel 2 = 153 pagesLevel 3 = 2 pagesLevel 4 = 1 page - root.So it's a 5 level index for a million row table with huge rows and a rather large clustered index key. It's not 5 times less efficient than a RID lookup, because the upper levels will likely be in cache (where physical position on disk is irrelevant). It is a little less efficient, which is another reason why the small clustered index key guideline exists. The smaller the clustering key, the shallower the index tree and the more efficient the index seeks (which is what a lookup is) will be.Feel free to test it out. If you find that a heap is more efficient, and that couple milliseconds gained is critically important, and the downsides of a heap are not relevant, then go ahead and drop your cluster. There are specific cases (insert-heavy tables usually) where having no cluster is beneficial. It's not good in general though.</description><pubDate>Thu, 11 Mar 2010 12:08:22 GMT</pubDate><dc:creator>GilaMonster</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Yes I read part 3, and covering indexes are a good thing for us to think about.But it's hard for me to imagine how traversing a (clustered) B-tree in a large table, which surely involves reading several pages which may be widely spaced, is just about the same as following a pointer which tells the system exactly which page to read without any other pages being accessed.The only way I can see a near-equivalency here is if many or most of the clustered tree pages are cached in memory, but even so, that only takes you so far.</description><pubDate>Thu, 11 Mar 2010 11:25:56 GMT</pubDate><dc:creator>wodom</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]wodom (3/11/2010)[/b][hr]That would seem to imply that to avoid the extra work, maybe it's better to have no clustered index, in which case SQL Server can always use the row ID to go quickly and directly to the row without another lookup. Is there something wrong with this logic?[/quote]If there's no cluster then SQL has to do a RID lookup to find the actual row. That's just about the same amount of work as for a clustered index seek. They're both very expensive operations and are done row by row.See part 3 for a discussion of nonclustered indexes. I think I talk about covering indexes in there.</description><pubDate>Thu, 11 Mar 2010 11:00:50 GMT</pubDate><dc:creator>GilaMonster</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>you can add included columns to your nonclustered indexes to minimize RID Lookups</description><pubDate>Thu, 11 Mar 2010 10:23:06 GMT</pubDate><dc:creator>alen teplitsky</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]GilaMonster (3/11/2010)[/b][hr]if it's a vendor app that you can't change, then that's pretty much that, you can't change it.[/quote]Well, we can't change the width or contents of that field, but we can make its index clustered or not, and we might be able to find a smaller field to use as a clustered index.Something else has started bothering me: If there's a clustered index, then all nonclustered indexes must use it to find the record? That seems to be saying that SQL Server essentially has to do two separate index lookups. That would seem to imply that to avoid the extra work, maybe it's better to have no clustered index, in which case SQL Server can always use the row ID to go quickly and directly to the row without another lookup. Is there something wrong with this logic?</description><pubDate>Thu, 11 Mar 2010 09:28:46 GMT</pubDate><dc:creator>wodom</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>As always, it depends.26 bytes isn't that big, it's not as if we're talking a 400 byte index key. Also, if it's a vendor app that you can't change, then that's pretty much that, you can't change it.</description><pubDate>Thu, 11 Mar 2010 01:17:35 GMT</pubDate><dc:creator>GilaMonster</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>I'd like an opinion. Part 2 of the article (which I'm just now reading) says a clustered index should be narrow, unique, unchanging, and ever-increasing. I have tables (some quite large) with an important key that definitely qualifies on points 2, 3, and 4, but the key length is char(26). Not the most narrow key in the world.The key length and contents is specified by 3rd-party software and we can't change it. Since the characters are all digits, I've tried changing the datatype to decimal, which packs it into 13 bytes, but some database operations fail when I do that and I had to change it back. (Chasing down the exact reason and fixing it is not very viable because there are hundreds of separate instances that would need changing, and no I can't make it a common routine because of the way the code is generated from the 3rd-party system.)This field is heavily used for lookups and changes during the (brief) data entry phase, and is also used later during reporting.My question is, is this key too wide to consider for a clustered index, or not? Generally it's not a large percentage of the entire row width, but if this value gets included into every other index (each table generally has 1 to 4 others), that gives me pause.</description><pubDate>Wed, 10 Mar 2010 11:06:46 GMT</pubDate><dc:creator>wodom</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Grate article!You should put all of your articles in a book if you don't have one already.  I will definitely buy it.  Your English is a mercy for nonnative English speaker like me.  I don't know why some IT authors love to use big words in their books. :PSome comments are funny and I love your replies.....moving on to the Part 3.</description><pubDate>Sun, 21 Feb 2010 18:38:24 GMT</pubDate><dc:creator>jungnaja</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>Tom, it wasn't your post(s).  Talltop and I had a spat.</description><pubDate>Thu, 21 Jan 2010 06:35:41 GMT</pubDate><dc:creator>TheSQLGuru</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]Tom.Thomson (1/20/2010)[/b][hr]Can you delete it for me?[/quote]I can't. Only mods have the permissions to delete posts. If you wish, just edit it and remove (or alter) what you said.I saw nothing problematic or controversial in your first post either. I use 'it depends' on a regular basis, because it does. I'm always happy to discuss in detail what exactly it depends on.</description><pubDate>Thu, 21 Jan 2010 01:18:41 GMT</pubDate><dc:creator>GilaMonster</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]GilaMonster (1/20/2010)[/b][hr]Gentlemen, can you drop this please. It's not appropriate for the thread's topic and I'd rather not have Steve come and lock this because it got out of hand.Thank you.[/quote]Ouch - that may be my fault (as I can't see anything else that might be that controversial) - and I've already posted another comment before I saw this.  Can you delete it for me?Tom</description><pubDate>Wed, 20 Jan 2010 18:36:57 GMT</pubDate><dc:creator>L' Eomot Inversé</dc:creator></item><item><title>RE: Introduction to Indexes: Part 2 – The clustered index</title><link>http://www.sqlservercentral.com/Forums/Topic816989-1390-1.aspx</link><description>[quote][b]talltop-969015 (1/20/2010)[/b][hr]I have gotten people fired in the past who say "it depends" all the time. Either give me a straight non-convoluted answer, or keep quiet or just say I don't know.[/quote]You are lucky you never worked for me.  And of course now you never will!  If that's your response to a very clear staement of exactly what it depends on (involving a dependency on information that clearly is NOT available to the person making the statement) you are, in my view, being silly.</description><pubDate>Wed, 20 Jan 2010 18:32:43 GMT</pubDate><dc:creator>L' Eomot Inversé</dc:creator></item></channel></rss>