2.Inaccurate Cardinality Estimate Detection Framework
クエリのパフォーマンスが低下する原因にはさまざまな原因がありますが、その中のひとつに、オプティマイザのカーディナリティ見積もりが適切でないことが原因でパフォーマンスが低下することがあります。オプティマイザがカーディナリティを適切に見積もることができない原因の多くは、統計情報の不足や、適切なインデックスが付与されてないことが原因ですが、不正な見積もりで生成された実行プランに従って実行されるクエリは、長時間処理が完了しないという性質上、実行プランのどの処理(オペレータ)の見積もりに実際と乖離があったのかを特定することが困難でした。なぜなら、各オペレータの見積もり行数と、実際に処理した行数の件数を確認するには、statistics xml (または statistics profile )オプションをオンに設定してクエリを実行する必要がありますが、このオプションで取得できる情報は、クエリの実行が完了した後にしか出力されないからです。
SQL Server 2012では、このような不正なカーディナリティ見積もりに関する問題をより簡単に解析するために、cardinality estimate frameworkというものを拡張イベントで実装しました。このイベントの名前は、inaccurate_cardinality_estimateです。inaccurate_cardinality_estimateイベントは、クエリの実行中にオペレータの出力件数が、見積もりと一定量異なったタイミングで随時発生しますので、クエリの完了を待たずとも見積もりとの乖離が発生したオペレータを知ることができます。
検知アルゴリズム
カーディナリティの見積もりと実際が乖離していることを検知する (つまり、inaccurate_cardinality_estimateイベントを発生させる) アルゴリズムは、以下のように実装されています。
• 見積もり行数が1行の場合
オプティマイザがオペレータの見積もり行数を0行と見積もったケースです。オプティマイザの実装上の理由で、オペレータには少なくとも1行以上のデータを処理するよう設定されていないといけないので、オプティマイザが0行と見積もった場合、オペレータの見積もり行数が1行となります。この場合、実際にオペレータが2行以上処理するとイベントが発生します。
• 見積もり行数が2から100,000の場合
見積もり行数が、2から100,000行の場合、見積もり行数の5倍以上の行数をオペレータが処理するとイベントが発生します。
• 見積もり行数が100,000より大きい場合
見積もり行数が、100,000より大きい場合、イベントが発生するときの閾値は次の公式で算出されます。
公式: 100,000 * (5-1.2) + 1.2 *[見積もり行数].
以下の表は、この検知アルゴリズムで算出したときの見積もり行数とその閾値です。
見積もり行数 | 閾値(イベントが発生するときの実際の行数) |
1 | 2 |
2 | 10 |
50 | 250 |
100 | 500 |
250 | 1250 |
500 | 2500 |
1000 | 5000 |
10000 | 50000 |
50000 | 250000 |
100000 | 500000 |
100001 | 500001.2 |
250000 | 680000 |
500000 | 980000 |
750000 | 1280000 |
1000000 | 1580000 |
2000000 | 2780000 |
5000000 | 6380000 |
10000000 | 12380000 |
100000000 | 120380000 |
1000000000 | 1200380000 |