全文検索とLIKEとは


133

SQLの「全文検索」についての投稿を読んだところです。

FTSとLIKEの違いは何だろうと思っていました。私はいくつかの記事を読みましたが、それをうまく説明するものは何も見つかりませんでした。

回答:


164

一般に、「精度」と「再現率」の間にはトレードオフがあります。高精度とは、関連性の低い結果が表示される回数が少ない(誤検知がない)ことを意味し、再現率が高いと、不足している関連結果が少ない(誤検知がない)ことを意味します。LIKE演算子を使用すると、100%の精度でリコールの譲歩がありません。全文検索機能を使用すると、再現性を高めるために精度を調整する柔軟性が大幅に向上します。

ほとんどの全文検索の実装では、「逆索引」を使用しています。これは、キーが個々の用語であり、関連する値が用語を含むレコードのセットであるインデックスです。全文検索は、これらのレコードセットの共通部分、和集合などを計算するように最適化されており、通常、特定のレコードが検索キーワードにどれだけ強く一致するかを定量化するランキングアルゴリズムを提供します。

SQL LIKE演算子は非常に非効率的です。インデックス付けされていない列に適用すると、フルスキャンが使用されて一致が検索されます(インデックス付けされていないフィールドに対するクエリと同じように)。列にインデックスが付けられている場合、インデックスキーに対してマッチングを実行できますが、ほとんどのインデックスルックアップよりも効率ははるかに劣ります。最悪の場合、LIKEパターンには先頭のワイルドカードが含まれ、すべてのインデックスキーを調べる必要があります。対照的に、多くの情報検索システムでは、選択したフィールドのサフィックスツリーをプリコンパイルすることにより、先行ワイルドカードのサポートを有効にできます。

全文検索に典型的なその他の機能は次のとおりです。

  • 字句解析またはトークン化-非構造化テキストのブロックを個々の単語、フレーズ、および特殊なトークンに分解
  • 形態素解析、またはステミング-特定の単語のバリエーションを1つのインデックス用語に折りたたみます。たとえば、「マウス」と「マウス」、または「電化」と「電気」を同じ単語として扱う
  • ランキング-一致するレコードとクエリ文字列の類似性を測定する

2
ランキングは@VipinJainの回答
ychaouche

39

FTSでは、多くのレコードをすばやく検索できるように、テキストフィールド内の個々の単語にインデックスを付ける必要があります。LIKEを使用するには、フィールド内で文字列検索(線形など)を行う必要があります。


23

MySQLは、有効なフルテキスト検索列の単語からインデックスを作成し、このインデックスで検索を実行します。MySQLは高度なアルゴリズムを使用して、検索クエリと一致する行を決定します。

また、このSOの答えから:

全文検索にはいくつかの利点があります。

インデックス作成:

何かのようなもの:

WHERE Foo LIKE '%Bar';

インデックスを利用できません。すべての行を調べて、一致するかどうかを確認する必要があります。ただし、フルテキストインデックスは可能です。実際、フルテキストインデックスは、一致する単語の順序、それらの単語がどのくらい接近しているかなどの点で、はるかに柔軟性があります。

ステミング:

全文検索は単語をステミングできます。runを検索すると、「run」または「running」の結果を得ることができます。ほとんどのフルテキストエンジンには、さまざまな言語の語幹辞書があります。

加重結果:

フルテキストインデックスには複数の列を含めることができます。たとえば、「ピーチパイ」を検索すると、インデックスにタイトル、キーワード、本文を含めることができます。タイトルに一致する結果は、関連性が高いほど重みを高くしたり、並べ替えて上部に表示したりできます。

短所:

フルテキストインデックスは、標準のB-TREEインデックスより何倍も大きくなる可能性があります。このため、データベースインスタンスを提供する多くのホスティングプロバイダーは、この機能を無効にするか、少なくとも追加料金を請求します。たとえば、前回チェックしたところ、Windows Azureはフルテキストクエリをサポートしていませんでした。

フルテキストインデックスの更新も遅くなる可能性があります。データが大幅に変更される場合、標準のインデックスと比較して、インデックスの更新に遅れが生じる可能性があります。


16

Likeはワイルドカードのみを使用し、それほど強力ではありません。

フルテキストを使用すると、And、Or、Not、類似のサウンド結果(SOUNDEX)など、より多くの複雑な検索が可能になります。

SQLのCONTAINS()FREETEXT()および関連する全文検索項目を調べて、何が利用可能かをよりよく理解できるようにします。



11

実際の違いは、スキャン方法です。全文検索の場合、単語(用語)はハッシュキーとして使用されます。各キーは、キー(用語)が出現するドキュメントの配列に関連付けられています。次のようになります。

Document sets = {d1, d2, d3, d4, ... dn}
Term sets = {t1, t2, t3, .. tn}

用語ドキュメントマトリックス(どのドキュメントのどの用語メンバーか)は、次のように表すことができます。

t1 -> {d1, d5, d9,.. dn}
t2 -> {d11, d50, d2,.. dn}
t3 -> {d23, d67, d34,.. dn}
:
tn -> {d90, d87, d57,.. dn}

「単語/用語t1を含むすべてのドキュメントを取得してください」というリクエストがあった場合、ドキュメントセット {d1, d5, d9,.. dn }が返されます。

非正規化されたテーブルスキーマをハックしてドキュメントを保存できます。MySQLテーブルの各行は「ドキュメント」と見なされ、TEXT列には段落などが含まれます。逆索引には、ハッシュキーとしての用語と行IDが含まれます。ドキュメントIDとして。

このSQLクエリでは、多少のO(1)パフォーマンスがあることに注意してください。クエリは独立しています

  1. TEXT列の単語/用語の数
  2. 基準に一致する行/ドキュメントの数
  3. 単語/用語の長さ

たとえば、次のSQLを実行して、指定した単語XYZに一致するすべての行を抽出できます。

SELECT * 
FROM   my_table 
WHERE  MATCH (my_text_column) against ('XYZ' IN boolean mode) ;

警告:このクエリにORDER BYを追加すると、ランタイムはいくつかのパラメーターに基づいて変化します。そのうちの1つは、一致する行/ドキュメントの数です。注意してください。

LIKEはこれを何も持っていません。文/文字列を線形スキャンして、一致するすべての用語を見つけることが強制されます。ワイルドカードを追加すると混乱が増します。ご想像のとおり、長さが短い文字列には最適ですが、長い文では無残に失敗します。そして、段落やテキストのページ全体などを持っているときは間違いなく比較できません。


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