web-dev-qa-db-ja.com

全文検索とLIKE

私の質問はフルテキストの使用についてです。%で始まるクエリのように、インデックスを使用しないでください。

SELECT * from customer where name like %username%

このクエリにフルテキストを使用すると、パフォーマンスが向上しますか? SQL Serverは、%username%などのクエリにフルテキストインデックスの利点を使用できますか?

21
profvm

短い答え

SQLServerで中置検索を実行する効率的な方法はありません。インデックス付きの列でLIKEを使用することも、フルテキストインデックスを使用することもできません。

長い答え

一般的なケースでは、LIKE演算子に相当するフルテキストはありません。 LIKEは文字列に対して機能し、ターゲット内のすべてに対して任意のワイルドカードマッチを実行できますが、設計上、フルテキストは単語/用語全体に対してのみ機能します。 (これは少し単純化したものですが、この回答の目的には役立ちます。)

SQL Serverフルテキストは、プレフィックス用語演算子を使用したLIKEのサブセットをサポートします。ドキュメントから( http://msdn.Microsoft.com/en-us/library/ms187787.aspx ):

SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, ' "Chain*" ');

チェーンソー、チェーンメイルなどの名前の製品を返します。機能的には、これは標準のLIKE演算子(LIKE 'Chain%')、列にインデックスが付けられている限り、プレフィックス付き検索にLIKEを使用すると、許容できるパフォーマンスが得られます。

LIKE演算子を使用すると、ワイルドカードを任意の場所に配置できます。たとえば、LIKE '%chain'、そしてあなたが言ったように、これはインデックスが使用されるのを防ぎます。ただし、フルテキストの場合、アスタリスクはクエリ用語の最後にのみ表示されるため、これは役に立ちません。

LIKEを使用すると、isを作成して、効率的なpostfix検索を実行できます。新しい列、その値をターゲット列の逆に設定し、インデックスを作成します。次に、次のようにクエリを実行できます。

SELECT Name
FROM Production.Product
WHERE Name_Reversed LIKE 'niahc%'; /* "chain" backwards */

名前が「chain」で終わる商品を返します。

次に、プレフィックスと逆ポストフィックスハックを組み合わせることができると思います。

SELECT Name
FROM Production.Product
WHERE Name LIKE 'chain%'
AND Name_Reversed LIKE 'niahc%';

これは(潜在的に)インデックス付きの中置検索を実装しますが、特にきれいではありません(そして、クエリオプティマイザーがプランで両方のインデックスを使用するかどうかを確認するためにこれをテストしたことはありません)。

37

インデックスがどのように機能しているかを理解する必要があります。インデックスは百科事典の枯れ木版とまったく同じです。

使用する場合:

SELECT * from customer where name like username%

フルテキストまたはフルテキストなしのインデックスは機能するはずです。だが

SELECT * from customer where name like %username%

インデックスでは機能しません。そしてそれは時間のかかるクエリになります。

3
Ran Bar-Zik

次を使用できます。

SELECT * from customer where CONTAINS(name, 'username')

OR

SELECT * from customer where FREETEXT(name, 'username')
0
Rafiqul Islam

のように、含まれているものは非常に異なります-

次のデータ値を取ります

'ジョン・スミス' 'サム・スミス' 'ジョン・フラー'

's%' 'サム・スミス'のように

'%s%' 'ジョン・スミス' 'サム・スミス'のように

's'を含む

'john''john smith''johnfuller'が含まれています

's *' 'ジョン・スミス' 'サム・スミス'が含まれています

contains s contains s *と同じ値を返します-最初のアスタリスクは無視されます。これは少し面倒ですが、インデックスは文字ではなく単語です。

0
Ed Green

フルテキストインデックスについて私が知っていることのうち、次の外挿を行います。

  1. インデックスを作成すると、テキストが解析され、単語が検索され(MySQLなどの一部のRDBMSは、3文字より長い単語のみが考慮されます)、その単語がインデックスに配置されます。
  2. 全文索引で検索するときは、単語を検索してから、その行にリンクします。
  3. 私が最初の2つ(MSSQLの場合)について正しければ、4文字以上の長さのWORDSを検索した場合にのみ機能します。 「椅子」を検索しても「アームチェア」は見つかりません。

すべてが正しいと仮定して、先に進み、次のステートメントを作成します。フルテキストインデックスは実際にはインデックスであり、検索が高速になります。それは大きく、LIKEよりも検索の可能性が少ないですが、はるかに高速です。

より詳しい情報:
http://www.developer.com/db/article.php/3446891
http://en.wikipedia.org/wiki/Full_text_search

0
AlexanderMP