web-dev-qa-db-ja.com

特定のビューの上位(n)ソート最適化を無効にする

複雑なロジックと3レベルの深さ(ネストされたビュー)のビューがあります。複雑なため、実行計画を貼り付けることはできません。

ビューの目的はデータアナリストにビジネス分析を提供することなので、選択(上位N)クエリを実行してビューのサンプルをチェックするために使用するレポートを開発しています。

オプティマイザがこのビューに別の実行プランを選択しているため、ビュー内のこの(上位N)クエリのパフォーマンスは非常に悪い(afaik CQScanTopSortNew

ハッシュ結合 を使用するなど、上位(N)のユースケースに対していくつかの最適化を試みましたが、これは非上位(n)のユースケースを台無しにします。

非トップ(n)のパフォーマンスは良好です。ビューの構造や機能を大幅に変更せずに、オプティマイザがtop(n)句を持っている場合に、別の実行プランを選択しないようにするにはどうすればよいですか。

たとえば、ビュー内に個別の選択を追加すると、オプティマイザは常に正しいプランを選択しますが、ビューの機能は変わります。

6
Lucas

一般的に行の目標を無効にすることなく、ビューで目的を達成するための完全に透過的な方法は考えられません。これはおそらく目的に合わないでしょう。

ビューの目的はデータアナリストにビジネス分析を提供することなので、選択(上位N)クエリを実行してビューのサンプルをチェックするために使用するレポートを開発しています。

おそらく、代わりにTOP (x) PERCENTを使用するように説得できますか?これは、パーセンテージを計算するために、セット全体の行数を数える必要があります。フルセットの具体化にはtempdbのコストが伴いますが、データが妥当なサイズであれば、これは管理可能です。いずれにせよ、それは行のゴールのない計画を与えるでしょう。

SELECT TOP (1) PERCENT TV.* FROM TheView AS TV;

これは、任意の並べ替え順序(および物理的な並べ替えが必要であることが保証されている並べ替え順序)を選択するよりも、これがより自然である場合があります。

そうは言っても、詳細な調査により、TOPを使用したクエリをできるだけ速くするためのチューニングオプションが明らかになる可能性があります。ただし、これはコンサルティング作業であるため、見積もり計画のみに基づいてここで対処できる範囲を超えています。

11
Paul White 9

最初に、貼り付けたプランは推定実行プランでしたが、actual 実行計画。 SSMSを右クリックして[実行プランを表示]を選択したようですが、クエリを実行する前に[実際の実行プランを含める]を選択する必要があります。通常は同じですが、実際のプランには、各テーブル/インデックスによって返される実際の行数が含まれます。

そうは言っても、投稿した内容に基づいて、TOPクエリがシリアル実行プランを取得しているのに対し、非TOPクエリはパラレル実行プランを取得していることが問題であるようです。これは、オプティマイザが実行する作業がはるかに少ないと予想されるため、TOPクエリに割り当てるコストが低くなるため意味があります。

ドキュメントに記載されていない並列実行プランを強制する方法は、TRACEFLAG 8649を次のように使用することです。

select top 10 * 
from TheView
where Date = '2020-02-20'
option (querytraceon 8649)

ドキュメント化されていないものを本番環境で実行することは悪い考えです。幸い、Adam Machanicはmake_parallel()を作成しました: http://dataeducation.com/next-level-parallel-plan-forcing-an-alternative-to-8649/

このように使用します。

select top 10 * 
from TheView
CROSS JOIN dbo.make_parallel()
where Date = '2020-02-20';

考慮すべきもう1つの点は、TOP句にORDER BY句を含めないことです。順序が重要でない場合は、別のORDER BYを試してみてください。ソートを強制すると、並列プランが強制される場合があります。

1
Alan Burstein