web-dev-qa-db-ja.com

MATCH AGAINSTまたはLIKEのどちらのSQLクエリが優れていますか?

「foo_desc」列と「bar_desc」列のいずれかに「foo」と「bar」の両方のキーワードがある行をデータベースで検索するには、次のようにします。

SELECT * 
FROM t1 
WHERE MATCH (t1.foo_desc, t2.bar_desc) AGAINST ('+foo* +bar*' IN BOOLEAN MODE)

または

SELECT * 
FROM t1 
WHERE (CONCAT(t1.foo_desc, t2.bar_desc) LIKE '%foo%') AND (CONCAT(t1.foo_desc, t2.bar_desc) LIKE '%bar%')

最後のクエリのマイナス面はパフォーマンスです。

利点は、LIKEクエリがMATCH AGAINSTが検出しない「xxfoo」を検出することです。

どちらが好ましいですか、またはより良い解決策はありますか?

66
Wil

更新

MySQL 5.6以降、InnoDBテーブルはMatch... Against


最初はmuchより良いです。 MyISAMテーブルでは、それらの列に対してフルテキストインデックスを使用します。もう1つは、すべての行で連結を実行してから比較を実行する全表スキャンを実行します。

LIKEは、以下に対して実行している場合にのみ効率的です。

  • 列(特定のデータベースベンダーが機能インデックス(Oracleなど)をサポートしていて、それらを使用している場合を除き、関数の結果ではありません);
  • 列の開始(つまりLIKE 'blah%' とは対照的に LIKE '%blah%');そして
  • インデックスが付けられた列。

これらの条件のいずれかが当てはまらない場合、SQLエンジンがクエリを実行する唯一の方法は、全表スキャンを実行することです。これは、約1万から2万行で使用できます。ただし、すぐに使用できなくなります。

注: MySQLのMATCHの1つの問題は、単語全体に対してのみ一致するように見えるため、 'bla'の検索は 'blah'の値を持つ列には一致しないが、 'bla *'になります。

63
cletus