web-dev-qa-db-ja.com

数百万行のテーブル、MySQLでのLIKEクエリのパフォーマンス

実際の経験を持つ人なら誰でも、フィールドにプレーンなINDEXがある場合、速度と効率の観点から、LIKEクエリはMySQLで数百万行のテーブルに対してどのように実行されますか?

数百万行のテーブルでデータベースフィールド検索を実行するためのより良い代替手段(FULLTEXT 50%ルールのように結果を除外しない)はありますか?

例:

Schema (comments table)

id (PRIMARY) title(INDEX) content time stamp

Query

SELECT * FROM 'comments' WHERE 'title' LIKE '%query%'
18
roozbubu

実際の経験を持つ人なら誰でも、フィールドにプレーンなINDEXがある場合、速度と効率の観点から、LIKEクエリはMySQLで数百万行のテーブルに対してどのように実行されますか?

あまりよくありません(私は900kの範囲でいくつかの検索を行ったと思いますが、数百万行のLIKEの経験があるとは言えません)。

通常、検索はできる限り制限する必要がありますが、これはテーブル構造とアプリケーションのユースケースによって異なります。

また、一部のWebユースケースでは、個別のキーワードにインデックスを付けたり、キーワードテーブルとrows_contains_keywordを作成したりするなど、いくつかのトリックでパフォーマンスとユーザーエクスペリエンスを実際に向上させることができます。 (id_keyword、id_row)テーブル。キーワードテーブルはAJAXとともに使用され、検索語(単純な単語)を提案し、それらを整数--id_keywordsにコンパイルします。その時点で、それらのキーワードを含む行を見つけると本当に高速です。一度に1行ずつテーブルを更新することも非常にパフォーマンスが高く、もちろん、バッチ更新は確実に「しない」ようになります。

+演算子のみを使用する場合、これは フルテキストMATCH..IN BOOLEAN MODE によってすでに行われていることとそれほど変わりません。

SELECT * FROM arts WHERE MATCH (title) AGAINST ('+MySQL +RDBMS' IN BOOLEAN MODE);

おそらく、InnoDBテーブルでそれを実行する必要があります。

ブール全文検索には、次の特徴があります。

  • 関連性の高い順に行を自動的にソートすることはありません。 .。
  • InnoDBテーブルでは、ブールクエリを実行するために、MATCH()式のすべての列にFULLTEXTインデックスが必要です。 MyISAM検索インデックスに対するブールクエリは、FULLTEXTインデックスがなくても機能しますが、この方法で実行される検索は非常に遅くなります。 .。
  • MyISAM検索インデックスに適用される50%のしきい値は使用しません。

特定のケースについて詳しく教えてください。

8
LSerni

パターンの先頭に%がある場合、LIKEは全表スキャンを実行します。

(自然言語ではなく)ブールモードでFULLTEXTを使用して、50%ルールを回避できます。

ブール全文検索には、次の特徴があります。

50%のしきい値は使用しません。

http://dev.mysql.com/doc/refman/5.0/en/fulltext-boolean.html

15
Eric J.

LIKE '%something'は全表スキャンを保証するため、他の句(日付範囲など)によってクエリを制限することをお勧めします。

8

Workbenchでは、SELECTの前にEXPLAINを使用して、検索語のさまざまな部分にワイルドカードを使用して、INDEXを使用する場合と使用しない場合のLIKEのさまざまな条件の使用をテストします。それぞれのケースは特定のケースであるため、テストに基づいて独自の結論を得ることができます。

0