インデックスに関連するNOTロジックの使用


12

Microsoftのデータベース開発試験70-433に関する本:Microsoft SQL Server 2008 Database Developmentによると

NOTロジックではなく先頭のワイルドカード文字のいずれも、クエリオプティマイザーがインデックスを使用して検索を最適化することを許可しませ。最適なパフォーマンスを得るには、NOTキーワードと先頭のワイルドカード記号を使用しないでください。

することを取った私はそうNOT INNOT EXISTSなど

さて、このSOの質問に関して、@ GBNが選んだ解決策は上記の声明に違反すると考えました。

どうやら、そうではありません。

だから私の質問は:なぜですか?

回答:


21
  • NOT IN (SELECT ...)そしてNOT EXISTS (SELECT .. WHERE correlation..)「Anti Semi Joins」です。つまり、認識されたセットベースの操作

  • WHERE NOT (MyColumn = 1) すべての行を見る必要があるフィルターです

詳細については、以下を参照してください。

編集:完全を期すために

LEFT JOINはしばしばパフォーマンスが低下します。http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-serverを参照してください

この同じサイトは、MySQLではNOT EXISTSは他のRDBMSのように最適化されておらず、LEFT JOINの方が優れていることを示しています

SQL Serverでは、LEFT JOINはNOT EXISTSと同様に実行されないことを経験から知っています。また、別の処理ステップと同じ結果を得るためにDISTINCTが必要になることもよくあります。


0

これにはサブセレクトを使用します:

SELECT m* from Main AS m 
    WHERE m.id NOT IN 
        (SELECT m2.id FROM Main AS m2 
           WHERE m2.id IN (...possibly null/empty list goes here...));

もちろん、テーブルが大きい場合は、これを分析してパフォーマンスを確認することをお勧めします。メインクエリの結果をフィルタリングする追加の句がある場合は、サブセレクトでそれらを複製する必要があります。ただし、サブセレクトには「IN」と「NOT IN」があるため、サイズの結果が異なる可能性があり、通常はクエリのパフォーマンスが重要になるため、大きなテーブルで使用する場合はこのアプローチを分析してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.