2009-04-28 7 views
181

sargableは、少なくともクエリのエンジンがクエリが使用する実行計画を最適化することができるという意味です。私は答えを見てみましたが、主題に関してはあまりないようです。だから問題は、SQLクエリをsargableにするかどうかです。どんなドキュメンテーションも非常に高く評価されます。参考のためSQL文をsargableにするには?

+41

+1 "sargable"。それは今日の私の言葉です。 :-p – BFree

+25

SARG = ARGumentを検索します。面白いのは、ドイツ語で「SARG」は「棺」を意味するので、人々がSARGABLEについて話をするとき、いつも笑顔にしなければならない - 棺に入れることができるか? :-) –

+0

sargabilityは、お使いの環境によって異なります。 MySQLのドキュメントは次のとおりです:http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html –

答えて

178

最も一般的なものはは、where句で機能内のフィールドを含めるために非検索引数可能である存在する場合でも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()) 
+6

'GROUP BY'の中に関数を含めると、クエリは非sargableになりますか? –

+0

@MikeBantegui GROUP BYにフィールドを含めても、必ずしもそれを非sargeableにするわけではありません。正しいインデックスは間違いなくGROUP BYクエリに役立ちます。 – BradC

+1

*一部のデータベースエンジン(Oracle、PostgreSQL)は式のインデックスをサポートしていますが、dontchaは知っていますか? – Craig

62

Sargableはこれをしないでください。 LIKE値はワイルドカード文字で始まっているので、テーブル/インデックス・スキャンを起こし

WHERE Field LIKE '%blah%' 

WHERE FUNCTION(Field) = 'BLAH' 

テーブル/インデックス・スキャンを引き起こすこと:

はこれをしないでください。

データベースサーバーは、テーブル内のすべての行に対してFUNCTION()を評価し、それを 'BLAH'と比較する必要があります。

可能な場合は、逆にそれを行う:

WHERE Field = INVERSE_FUNCTION('BLAH') 

この度パラメータに対するINVERSE_FUNCTION()を実行すると、まだインデックスの使用が可能になります。 SQLオプティマイザはインデックスを上使用することはできません

SELECT ... FROM ... 
WHERE Year(myDate) = 2008 

:クエリを行います

+3

あなたの提案は、実際には、関数がデータを往復するとき(つまりf(f(n))= nを意味する)にしか機能しません。 –

+4

真。私はINVERSE_FUNCTIONを追加することを考えましたが、混乱したくありませんでした。私はそれを変更します。 – beach

7

をこの答えでは、私は、データベースが十分カバーするインデックスを持っていると仮定します。 this topicについて十分な質問があります。

多くの場合、クエリの可能性は、関連するインデックスのティッピングポイントによって決まります。ティッピングポイントは、あるテーブルまたは結果セットを別のテーブルまたは結果セットに結合しながら、インデックスの検索とスキャンの違いを定義します。もちろん、1つのシークはテーブル全体をスキャンするよりもはるかに高速ですが、多くの行を検索する必要がある場合は、スキャンが理にかなっています。

このように、オプティマイザが、あるテーブルの結果行の数が、次のテーブルの可能なインデックスのティッピングポイントよりも小さいと予想すると、SQL文が発生しやすくなります。

詳細な投稿と例hereがあります。

0

sargableと見なされる操作では、既存のインデックスを使用できるだけでは不十分です。上記の例では、where句のインデックス付きカラムに対して関数呼び出しを追加すると、定義済みのインデックスを利用する可能性が高くなります。それは、別名でその列(インデックス)からすべての値を検索し、次に提供されたフィルタ値に一致しない値を取り除きます。行数の多い表ではまだ効率的ではありません。 実際にsargabilityを定義するのは、ソートされたアイテム配列の半分セットの削除に依存するバイナリ検索メソッドを使用してb-treeインデックスをトラバースするクエリ機能です。 SQLでは、実行計画に「索引検索」として表示されます。

関連する問題