30.06.2013 Views

SQL Server Team-based Development - Red Gate Software

SQL Server Team-based Development - Red Gate Software

SQL Server Team-based Development - Red Gate Software

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

327<br />

Chapter 11: <strong>SQL</strong> Refactoring<br />

Random I/O access when filtering on non-clustered indexes<br />

Unless you adopt a particularly reckless approach to indexing, it's highly unlikely that<br />

every column in a table will be covered by an index. If you use SELECT * in a query, and<br />

so return columns that aren't really required, you will probably end up doing a clustered<br />

index scan, when it might well have been possible to perform an efficient index seek, if<br />

only the necessary data been requested.<br />

For clustered tables (i.e. tables with a clustered index), all data is stored in clustered<br />

index leaf pages. Non-clustered indexes only contain the clustering key and the data for<br />

columns on which the index is defined. These columns can be retuned via an index seek<br />

operation, but if a query requests any additional columns then the data is looked up in the<br />

clustered index. This lookup has had different names in last few years, such as "bookmark<br />

lookup" or "KEY lookup." It is a random access I/O operation, which is very expensive.<br />

INCLUDED columns<br />

<strong>SQL</strong> <strong>Server</strong> 2005 introduced a feature called INCLUDED columns by which we can include extra columns<br />

in the leaf level of a non-clustered index. For more information, refer to Books Online.<br />

If your use of SELECT * forces bookmark lookups, as it inevitably will, then the optimizer<br />

may quickly decide to abandon the "index seek + book markup lookup" route in<br />

favor of a full index scan. The reason is that an index scan is a sequential I/O operation,<br />

and can be more optimal than performing a moderate number of random I/O operations,<br />

even if the former ends up reading much more data.<br />

The threshold at which this switch is made will vary from system to system, so you<br />

should run tests on your system. Listing 11-8 shows the code explaining the problem<br />

with bookmark lookups, when using SELECT *.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!