定義により(少なくとも私が見た限りでは)引数を指定できるということは、クエリが使用する実行プランをクエリエンジンが最適化できるようにすることを意味します。私は答えを調べてみましたが、主題について多くはないようです。だから問題は、SQLクエリを検索可能にするものとは何ですか?どんなドキュメントでも大歓迎です。
参考:SARGable
定義により(少なくとも私が見た限りでは)引数を指定できるということは、クエリが使用する実行プランをクエリエンジンが最適化できるようにすることを意味します。私は答えを調べてみましたが、主題について多くはないようです。だから問題は、SQLクエリを検索可能にするものとは何ですか?どんなドキュメントでも大歓迎です。
参考:SARGable
回答:
クエリが引数を使用できないようにする最も一般的なことは、where句の関数内にフィールドを含めることです。
SELECT ... FROM ...
WHERE Year(myDate) = 2008
SQLオプティマイザは、myDateにインデックスが存在する場合でも、それを使用できません。文字通り、テーブルのすべての行に対してこの関数を評価する必要があります。使用するのがはるかに良い:
WHERE myDate >= '01-01-2008' AND myDate < '01-01-2009'
その他の例:
Bad: Select ... WHERE isNull(FullName,'Ed Jones') = 'Ed Jones'
Fixed: Select ... WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL))
Bad: Select ... WHERE SUBSTRING(DealerName,4) = 'Ford'
Fixed: Select ... WHERE DealerName Like 'Ford%'
Bad: Select ... WHERE DateDiff(mm,OrderDate,GetDate()) >= 30
Fixed: Select ... WHERE OrderDate < DateAdd(mm,-30,GetDate())
GROUP BY
と、クエリが検索不可能になりますか?
WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL))
もSELECT... FROM ... WHERE FullName = 'Ed Jones' UNION SELECT...FROM...WHERE FullName IS NULL
?最適化の担当者から、OR句をwhere句で使用するとクエリの検索を解除できると言われました。
Select ... WHERE isNull(FullName,'Ed Jones') = 'Ed Jones'
とSelect ... WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL))
。どちらもFullNameのインデックスを使用し、インデックスシークを実行します。
これを行わないでください:
WHERE Field LIKE '%blah%'
LIKE値はワイルドカード文字で始まるため、テーブル/インデックススキャンが発生します。
これを行わないでください:
WHERE FUNCTION(Field) = 'BLAH'
これにより、テーブル/インデックススキャンが発生します。
データベースサーバーは、テーブルのすべての行に対してFUNCTION()を評価し、それを「BLAH」と比較する必要があります。
可能であれば、それを逆に行います。
WHERE Field = INVERSE_FUNCTION('BLAH')
これにより、パラメーターに対してINVERSE_FUNCTION()が1回実行され、引き続きインデックスを使用できます。
この回答では、データベースに十分なカバリングインデックスがあると思います。このトピックについて十分な質問があります。
多くの場合、クエリの検索可能性は、関連するインデックスの転換点によって決定されます。転換点は、1つのテーブルまたは結果セットを別のテーブルまたは結果セットに結合するときのインデックスの検索とスキャンの違いを定義します。もちろん、1つのシークはテーブル全体をスキャンするよりもはるかに高速ですが、多数の行をシークする必要がある場合は、スキャンの方が理にかなっています。
したがって、オプティマイザが1つのテーブルの結果の行の数が次のテーブルの可能なインデックスの転換点よりも少ないことを期待している場合、SQLステートメントは特にsargableです。
詳細な投稿と例については、こちらをご覧ください。
操作が検索引数可能と見なされるためには、既存のインデックスを使用できるだけでは不十分です。上記の例では、where句のインデックス付きの列に対して関数呼び出しを追加しても、定義されたインデックスを利用する可能性が高くなります。「スキャン」、つまりその列(インデックス)からすべての値を取得し、指定されたフィルター値に一致しない値を削除します。それでも、行数が多いテーブルには十分効率的ではありません。sargabilityを実際に定義しているのは、ソートされた項目配列のハーフセット除去に依存するバイナリ検索メソッドを使用して、Bツリーインデックスをトラバースするクエリ機能です。SQLでは、これは「インデックスシーク」として実行プランに表示されます。