DOWNLOAD THE CODE:
Download the Code 94884.zip

As you're probably aware, one of the most important tasks that the SQL Server query optimizer performs is to determine which index (or set of indexes) to use for each table in a query. As each query is being optimized, SQL Server keeps track of indexes that the optimizer determines might have been useful by establishing the best possible index for each search argument in your WHERE clause and for each lookup done through a join. SQL Server 2005 then makes information about missing indexes available to you through two components. First, SQL Server provides a set of metadata objects to supply information about missing indexes. Second, for each query, information about missing indexes is available in the XML query plan. I'll explain the missing-index metadata, which can help you improve query performance, and next month I'll provide more details about working with the missing-indexes feature, including accessing missing-index information in your XML query plans.

Missing-Index Metadata
SQL Server has four dynamic management objects that provide information about missing indexes.

dm_db_missing_index_details. This view returns one row for each index that the optimizer determined was missing and includes information about columns that should be created as key columns and columns that can be added to the index as included columns. (For more information about SQL Server 2005's "included columns" feature, see "Seek and You Shall Find," September 2005, InstantDoc ID 46929 and "10 Things to Love About SQL Server 2005," May 2005, InstantDoc ID 45930.) Each missing index is identified by a unique value called an index_handle.

dm_db_missing_index_group_stats. Missing indexes each belong to an index group, even when a group has only one index. In fact, in SQL Server 2005, a group will never have multiple indexes. Each index group appears in this view along with information about how many times this missing-index group could have been used and what kind of performance improvement might be expected if the indexes in the group were created. Each missing-index group is identified by a unique value called a group_handle.

dm_db_missing_index_groups. This view maps index_handle values to group_handle values; in this view, the missing-index–group values are in a column called index_group_ handle. Because there are no index groups with multiple indexes, you should see a one-to-one relationship between missing indexes and missing index groups. dm_db_missing_index_columns. This is the only function in the list and requires an index_handle as a parameter. The function returns a table containing a list of suggested columns needed to build the specified missing index.

Dissecting the Metadata
To delve into the metadata, first run the code in Listing 1, which makes copies of three tables from the AdventureWorks database and builds no indexes on them. Now run the query in Listing 2 and note the performance information. I'm running SQL Server 2005 with the November 2006 Community Technology Preview (CTP) of Service Pack 2 (SP2), and I get the results that Figure 1 shows for the logical reads component of STATISTICS IO. I get the results that Figure 2 shows for the execution-time component of STATISTICS TIME. The query plan indicates that all three tables are being scanned and that there's one loop join with the very small dbo.Territory table as the outer table and a second, hash join.

We can now inspect the dm_db_missing_ index_details view. As of SP2, SQL Server allows an optional second parameter for the object_name function. If you're still using SP1, you can invoke object_name with only the first parameter, as long as you're in the AdventureWorks database.

The query results in Table 1 show two recommended indexes, each of which SQL Server could use in a query that compares a single column to a constant. In the dbo.Customers table, we're looking for a particular TerritoryID value—2 in this example. The query also uses TerritoryID as the join key with the Territory table, so when Customers is the inner table in that join, the lookup to find the matching rows uses the TerritoryID column. The query uses the dbo.OrderHeader table as the inner table in a join, searching for matches on the CustomerID column, so the optimizer also recommends building an index on the CustomerID column of the dbo.OrderHeader table.

   Prev. page   [1] 2     next page



You must log on before posting a comment.

If you don't have a username & password, please register now.

Reader Comments

excellent article....explained very clearly about missing index features in sql 2005

rsqlmag

Article Rating 5 out of 5