テーブルを使用して不足しているインデックスを見つける方法について、SQL Server2008に関連するさまざまな記事を読みましたsys.dm_db_missing_index_groups
、sys.dm_db_missing_index_group_stats
など。
私が知りたいことの1つ:これらのインデックスから利益を得るクエリを抽出することは可能ですか?
皆さんありがとう!
私が使用したいアプローチの1つは、最も頻繁に実行されるクエリだけに焦点を当てることであり、インデックスを持つことでメリットが得られる可能性のあるすべてのクエリに焦点を当てることはありません。この理由は、追加のインデックスがDML(DATA MODIFICATION LANGUAGE)ステートメントに与える影響とコスト(CPU時間、I/O)です。
非クラスター化インデックスを持たない4つの列(id_customer、first_name、last_name、address)を持つテーブルcustomersを想像してみてください。
クエリUPDATE customers SET first_name = 'fred' where id_customer = '1'
テーブルcustomersのみを更新します。 idx_cust_first_lastという名前のfirst_nameとlast_nameに非クラスター化インデックスを追加する場合、上記の同じ更新ステートメントで、テーブルcustomersだけでなく、影響を受ける1つまたは複数の行のインデックスidx_cust_first_lastも変更する必要があります。これにより、追加のIOと、インデックスなしでは存在しないCPUコストが発生します。
つまり、インデックスが欠落しているインデックスビューに表示されるからといって、そのインデックスから得られるメリットがデータに加えられた変更の均等なコストを上回ることが確実になるまで、インデックスを追加する必要があるという意味ではありません。
これは、キンバリー・トリップが書いた、役立つと思われるテーマに関する記事への リンク です。
とは言うものの、これは、累積実行時間の合計に基づいて、インデックスが欠落しているクエリを降順で表示するために使用するクエリです。そのため、完了するまでに長い時間がかかるクエリがリストの一番上に表示されます。私の経験では、execution_count列は非常に重要です。これは、実行回数が、そのクエリが実際にどれだけ「人気がある」かを示しているためです。 total_elapsed_time列に示されているように、クエリの実行に非常に長い時間がかかるが、5回しか実行されなかった場合、そのクエリはたまにしか実行されないため、インデックスを追加しても役に立たない場合があります。
これがスクリプトです。私のものではありません。
WITH XMLNAMESPACES ('http://schemas.Microsoft.com/sqlserver/2004/07/showplan' AS sp)
SELECT p.query_plan.value(N'(sp:ShowPlanXML/sp:BatchSequence/sp:Batch/sp:Statements/sp:StmtSimple/sp:QueryPlan/sp:MissingIndexes/sp:MissingIndexGroup/sp:MissingIndex/@Database)[1]', 'NVARCHAR(256)') AS DatabaseName
,s.sql_handle
,s.total_elapsed_time
,s.last_execution_time
,s.execution_count
,s.total_logical_writes
,s.total_logical_reads
,s.min_elapsed_time
,s.max_elapsed_time
,p.query_plan
,p.query_plan.value(N'(sp:ShowPlanXML/sp:BatchSequence/sp:Batch/sp:Statements/sp:StmtSimple/sp:QueryPlan/sp:MissingIndexes/sp:MissingIndexGroup/sp:MissingIndex/@Table)[1]', 'NVARCHAR(256)') AS TableName
,p.query_plan.value(N'(/sp:ShowPlanXML/sp:BatchSequence/sp:Batch/sp:Statements/sp:StmtSimple/sp:QueryPlan/sp:MissingIndexes/sp:MissingIndexGroup/sp:MissingIndex/@Schema)[1]', 'NVARCHAR(256)') AS SchemaName
,p.query_plan.value(N'(/sp:ShowPlanXML/sp:BatchSequence/sp:Batch/sp:Statements/sp:StmtSimple/sp:QueryPlan/sp:MissingIndexes/sp:MissingIndexGroup/@Impact)[1]', 'DECIMAL(6,4)') AS ProjectedImpact
,ColumnGroup.value('./@Usage', 'NVARCHAR(256)') AS ColumnGroupUsage
,ColumnGroupColumn.value('./@Name', 'NVARCHAR(256)') AS ColumnName
FROM sys.dm_exec_query_stats s
CROSS APPLY sys.dm_exec_query_plan(s.plan_handle) AS p
CROSS APPLY p.query_plan.nodes('/sp:ShowPlanXML/sp:BatchSequence/sp:Batch/sp:Statements/sp:StmtSimple/sp:QueryPlan/sp:MissingIndexes/sp:MissingIndexGroup/sp:MissingIndex/sp:ColumnGroup') AS t1 (ColumnGroup)
CROSS APPLY t1.ColumnGroup.nodes('./sp:Column') AS t2 (ColumnGroupColumn)
WHERE p.query_plan.exist(N'/sp:ShowPlanXML/sp:BatchSequence/sp:Batch/sp:Statements/sp:StmtSimple/sp:QueryPlan//sp:MissingIndexes') = 1
ORDER BY s.total_elapsed_time DESC
そしてここに出力の例があります
ここに表示されるこのクエリは、現在実行されているか、すでにキャッシュにあります。サーバーの再始動またはdbccコマンドによってキャッシュが最近クリアされた場合は、表示する情報が少ない可能性があります。
キャッシュされたクエリプランに関する情報を返すために使用されている sys.dm_exec_query_plan および sys.dm_exec_query_stats に関するMicrosoftのドキュメント