質問
「全文検索」に関する記事を読みました。 SQLで。
FTSとLIKEの違いは何なのかと思っていました。いくつかの記事を読みましたが、それをうまく説明するものが見つかりませんでした。
解決
一般に、「精度」との間にはトレードオフがあります。および「リコール」。高精度とは、関連性の低い結果が少なく表示されること(誤検出なし)を意味し、高再現率とは、関連する結果が欠落する数が少ないこと(誤検出なし)を意味します。 LIKE演算子を使用すると、100%の精度が得られ、リコールの譲歩はありません。全文検索機能を使用すると、再現性を高めるために精度を調整する柔軟性が大幅に高まります。
ほとんどの全文検索の実装では、「反転インデックス」を使用します。これはキーが個々の用語であるインデックスであり、関連する値はその用語を含むレコードのセットです。全文検索は、これらのレコードセットの共通部分、結合などを計算するために最適化され、通常、特定のレコードが検索キーワードにどれだけ強く一致するかを定量化するランキングアルゴリズムを提供します。
SQL LIKE演算子は非常に効率が悪い場合があります。インデックスなしの列に適用すると、完全なスキャンを使用して一致するものが検索されます(インデックスなしのフィールドでのクエリと同様)。列にインデックスが付けられている場合、インデックスキーに対して照合を実行できますが、ほとんどのインデックス検索よりもはるかに効率が低下します。最悪の場合、LIKEパターンには、すべてのインデックスキーの調査を必要とする主要なワイルドカードが含まれます。対照的に、多くの情報検索システムでは、選択したフィールドでサフィックスツリーをプリコンパイルすることで、主要なワイルドカードのサポートを有効にできます。
全文検索の典型的なその他の機能は次のとおりです
- 字句解析またはトークン化— 非構造化テキストのブロック 個々の単語、フレーズ、および 特別なトークン
- 形態学的 分析、またはステミング—折りたたみのバリエーション 特定の単語を1つのインデックス用語に変換する。 たとえば、「マウス」の扱い。そして "マウス"または"電化"そして 「電動」同じ言葉として
- ランキング—測定 一致するレコードの類似性 クエリ文字列
他のヒント
FTSでは、多くのレコードをすばやく検索できるように、テキストフィールド内の個々の単語にインデックスを付けます。 LIKEを使用するには、フィールド内で文字列検索(線形など)を実行する必要があります。
MySQLは、有効な全文検索列の単語からインデックスを作成し、このインデックスで検索を実行します。 MySQLは洗練されたアルゴリズムを使用して、検索クエリと一致する行を決定します。
また、 SOの回答から:
全文検索にはいくつかの利点があります。
インデックス作成:
次のようなもの:
WHERE Foo LIKE '%Bar';
インデックスを利用できません。すべての行を調べて、一致するかどうかを確認する必要があります。ただし、フルテキストインデックスは可能です。実際、フルテキストインデックスを使用すると、一致する単語の順序、それらの単語がどれだけ近いかなどの点で柔軟性が大幅に向上します。
ステミング:
全文検索では単語をステミングできます。 runを検索すると、「ran」の結果を取得できます。または「実行中」。ほとんどのフルテキストエンジンには、さまざまな言語のステム辞書があります。
加重結果:
フルテキストインデックスには、複数の列を含めることができます。たとえば、「ピーチパイ」を検索すると、インデックスにタイトル、キーワード、本文を含めることができます。タイトルに一致する結果は、より関連性の高いものに重み付けしたり、上部近くに表示するように並べ替えることができます。
欠点:
フルテキストインデックスは、標準のB-TREEインデックスよりも何倍も大きくなる可能性があります。このため、データベースインスタンスを提供する多くのホストプロバイダーは、この機能を無効にするか、少なくとも追加料金を請求します。たとえば、最後に確認したように、Windows Azureはフルテキストクエリをサポートしていませんでした。
フルテキストインデックスの更新も遅くなる可能性があります。データが大きく変化する場合、標準インデックスと比較してインデックスの更新に多少の遅れが生じる可能性があります。
Likeはワイルドカードのみを使用し、それほど強力ではありません。
フルテキストを使用すると、And、Or、Not、同様のサウンド結果(SOUNDEX)、さらに多くのアイテムなど、より複雑な検索が可能になります。
SQL CONTAINS()FREETEXT()および関連する全文検索項目を調べて、利用可能なものをよりよく理解できるようにします。
実際の違いは、スキャン方法です。全文検索では、単語(用語)がハッシュキーとして使用されます。各単語は、キー(用語)が表示されるドキュメントの配列に関連付けられています。次のようになります。
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)のパフォーマンスが多少なります。クエリは
から独立しています- TEXT列の単語/用語の数
- 基準に一致する行/文書の数
- 単語/用語の長さ
たとえば、このSQLを起動して、指定された単語XYZに一致するすべての行を抽出できます。
SELECT *
FROM my_table
WHERE MATCH (my_text_column) against ('XYZ' IN boolean mode) ;
警告:ORDER BYをこのクエリに追加すると、ランタイムはいくつかのパラメーターによって異なります。パラメーターの1つは、一致する行/ドキュメントの数です。だから注意してください。
しかし、LIKEはこれについて何も持っていません。文/文字列を直線的にスキャンし、一致するすべての用語を見つける必要があります。ワイルドカードを追加すると混乱が増します。想像できるように、長さの短い文字列に対してはうまく機能しますが、長い文に対しては悲惨に失敗します。また、段落やページ全体のテキストなどがある場合は、比較できません。
FTSは、より効率的で強力です(特にワードブレーカーと語幹機能の場合) ...ただし、DBはすべての言語をサポートしていない場合があるため、要件を確認してください。たとえば、MSSQLはギリシャ語をサポートしていません(このページ http://msdn.microsoft.com/en-us/library/ms176076(v = sql.110).aspx )