SQL ServerでのLIKEとCONTAINSの比較


209

次のクエリのどちらが速いですか(LIKEとCONTAINSのどちらがいいですか)。

SELECT * FROM table WHERE Column LIKE '%test%';

または

SELECT * FROM table WHERE Contains(Column, "test");

12
答えを受け入れますか?
AgentFire

7
彼は何年も男ではありませんでした。
Chris

回答:


174

2つ目はCONTAINS何らかの形のインデックス(この場合はフルテキストインデックス)を使用できるため、より高速になるはずです(つまり、を意味し、実際に有効なクエリに入れます)。もちろん、この形式のクエリは、列がフルテキストインデックス内にある場合にのみ使用できます。そうでない場合は、最初のフォームのみが使用可能です。

LIKEを使用する最初のクエリは、ワイルドカードで始まるため、インデックスを使用できません。したがって、常に全テーブルスキャンが必要になります。


CONTAINSクエリは次のようになります。

SELECT * FROM table WHERE CONTAINS(Column, 'test');

@edze-つまり、私の最初の言及であるようにすでにリンクされている同じページCONTAINS?何?質問の元の形式は、Column CONTAIN("%test%",Column)>0どこが有効に近いものではありませんでした。それはまだ完全に正しくはありません。
Damien_The_Unbeliever

これは、SharePointでのクエリの整理に役立ちました。グレートアンサーバッジをもう1つお持ちください。
ouflak 2017

14

SQL Server 2012インスタンスで両方のクエリを実行したところ、私の場合、最初のクエリが最速であったことがわかります。

LIKEキーワードを使用したクエリは、クラスター化インデックススキャンを示しました。

CONTAINSは、全文一致とマージ結合のための追加の演算子を含むクラスター化インデックススキャンもありました。

予定


8
クラスタ化インデックスリーフページテーブルです。LIKE先頭にワイルドカードを含むクエリでは、インデックス部分を効率的に使用できません。全体をスキャンするだけで十分です。疑いなく、フルテキストインデックスを使用したクエリよりもCI全体のスキャンのパフォーマンスが高い場合があります(たとえば、非常に高い割合の行が一致する場合など)。これは、例外であり、「確認できる一般的なルールではありません」
Martin Smith

200,000件を超えるレコードをフェッチする実際の実行プランをよく見ています。両方のクエリをバッチに入れ、両方ともクラスター化インデックスをスキャンしましたが、「CONTAINS」クエリには、FULL TEXT MATCHとMERGE JOINの追加コストがかかります。
MI C

マージ結合を選択した場合、SQL Serverは、行のx%以上が述語と一致することになると推定しています。(ここでX = 転換点)。その場合、両方がかなり均等に一致することになると思います。実行プランに表示されるコストは、単なる見積もりです(実際のプランでも)。FTプランには追加の実行プラン演算子がありますが、いくつかの利点があります。マージ結合は、スキャン結果がFTの結果を使い果たしてしまう前に停止する可能性がありLIKEます。また、を評価する必要もありません。
マーティン・スミス

1
SQL 2012で実行プランを確認するために同様のクエリを実行し、インデックスシークを取得しました。たぶん、ここの例では、テーブルはほとんど空でした。場合によっては、SQLの方が高速であるため、インデックスを使用する代わりに非常に小さなテーブルでインデックススキャンを使用します。
フアン

8

クエリにダッシュ( "-")が含まれていたため、CONTAINS時間がかかり、使用されMergeたと思いますadventure-works.com

ダッシュはブレークワードであるため、CONTAINSはフルテキストインデックスをadventure検索works.comし、結果を検索してマージしました。


8

また、これから変更してみてください:

    SELECT * FROM table WHERE Contains(Column, "test") > 0;

これに:

    SELECT * FROM table WHERE Contains(Column, '"*test*"') > 0;

前者は「this is a test」や「test-case is a plan」などの値を持つレコードを検索します。

後者では、「これをテストしています」、「これは最大です」などの値を持つレコードも検索されます。


4
検索語の前後にアスタリスクを付けることはできますか?のドキュメントを読む際、CONTAINS「test *」のような接頭辞の用語の使用についてのみ言及しており、test」のような接尾辞の用語や「* test」のような完全な部分文字列の検索については言及していません。しかし、私はそれを試していません。
マットフォーサイス2016年

4
CONTAINSのドキュメント(docs.microsoft.com/en-us/sql/t-sql/queries/…)を読んだ場合、プレフィックスの検索のみがサポートされます。(コラム、「『含まれていて(SQL Severの中で)「これが最大である」私は、この実験的に何度も試してみましたが、見つけることはできませんテスト』」)
cl0rkster
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.