2017-09-14 9 views
1

複数のインデックス追加(カバリングされた非クラスタ化インデックスの追加)とクエリのリファクタリング/変更にもかかわらず、実行に非常に長い時間がかかります。 。完全な詳細に入ることなく、実行計画は以下の通りです。特に効率的でないか悪いと誰かに飛び出す何かがここにありますか?私はすべての主要なルックアップを取り除きました。インデックスシークを頻繁に使用しているように見えます。なぜなら、何とかしても膨大な時間を要すると私は混乱しています。クエリが実行されるとき、ボトルネックは明らかにCPU(ディスクI/Oではない)です。どんな考えにも感謝します。タフなSQL最適化

execution plan

+2

クエリとテーブル/インデックス構造も表示できますか? – Siyual

+2

また、実際のXMLプランをhttps://www.brentozar.com/pastetheplan/ –

+1

にアップロードしてください。「ここには、特に効率の悪い、悪いと思われるものはありますか?」ネストされたループjoins.https://i.stack.imgur.com/RrUxh.png –

答えて

0

OKだから一見大幅クエリの速度を助けたマーティンのコメントに基づいて変更を行いました。私は100%肯定的ではありません。これは解決策です。私はこれをたくさん実行しています。そして、それほど多くの基礎となるデータがメモリに入れられて、現在は高速になっている可能性があります。しかし、私は実際には本当の違いがあると思います。

特に、ネストされたループ内の3回のスキャンは、結果セットから完全に除外される小さなレコードセットを含む非常に小さなテーブルのサブクエリによって引き起こされていました。概念的には、クエリのようなものだった:

SELECT fields 
FROM (COMPLEX JOIN) 
WHERE id_field NOT IN (SELECT bad_ID_field FROM BAD_IDs) 

レコードがBAD_IDsに表示されている場合、それが結果に含まれてはいけませんということでアイデア。

私はこれに手を加えなどのものに変更: - それはBAD_IDsに任意のIDの結果を除外 -

SELECT fields 
FROM (COMPLEX JOIN) 
LEFT JOIN BAD_IDs ON id_field = bad_ID_field 
WHERE BAD_IDs.bad_ID_field IS NULL 

これは、論理的に同じものであるが、それは代わりに、サブクエリの結合を使用しています。実行計画さえほぼ同じです。 TOP操作はツリー内の他の場所でFILTERに変更されますが、クラスタード・インデックス・スキャンはまだ存在します。

しかし、それは非常に高速に実行されているようです!これは期待されていますか?私は常に、私が行った方法で使用されていたサブクエリはOKであり、サーバーは最も速い(おそらくほぼ同じ)実行計画を作成する方法を知っていると仮定していました。これは間違っていますか?

Thx!

+2

一般に私は 'NOT IN(SELECT ...'を 'NOT EXISTS'に書き換えます。時間が経つにつれて、これはクエリプランナによって最適化される可能性があります。 SQLのそれ以降のバージョンでは、これはまったく違いはありません。 –

+0

@ Nick.McDermaid - それは列のNULL可能性に依存します。私は可能なヌルに対処するための元の計画に余分な装置がないので、それらが「ヌルではない」と仮定します。 https://stackoverflow.com/a/11074428/73226 –

+0

新しい計画はどのように見えますか? –