2012-03-25 6 views
3

私は80万のレコードを持つテーブルを持っています。テーブルの構造:検索用にLIKEを使用する大きなMySQLテーブルの分割

  • ID - オートインクリメント、
  • コード - 5〜100文字の英数字コード、
  • 他のフィールド。

最も使用されるクエリは

SELECT * FROM table 
WHERE code LIKE '%{user-defined-value}%' 

あるクエリの数が増えているだけでなく、recodrsがカウントされます。まもなくパフォーマンスの問題が発生します。

部品を分割する方法はありますか?テーブルを最適化するための他の方法がありますか?

答えて

2

検索の先頭%がここのキラーです。インデックスの使用を無効にします。

私が考えることができるのは、コードの長さに基づいてテーブルを分割することだけです。

たとえば、入力されたコードが10文字の場合、先頭のパーセント記号のない10文字コードでテーブルを検索し、11文字コードで先頭のパーセント記号を使用してテーブルを検索し、先頭にパーセント記号が付いた12文字コードのテーブルなどがあります。

これは、決してマッチしない10文字未満のすべてのコードを検索する手間を省きます。また、検索の1つ(最初のもの)のインデックスを利用することもできます。

これはまた、テーブルサイズをいくらか小さくするのに役立ちます。

UNIONを使用すると、すべてのクエリを一度に実行できますが、おそらくクエリを動的に作成することをお勧めします。

また、FULLTEXTのインデックス作成がより良い解決策であるかどうかを確認する必要があります。

+0

実際には、 "%"の先頭の問題を解決するためにもう1つの列 "code_inverted"を追加しました。 私はあなたが示唆したようにコード長でテーブルを分割しようとします。 – Leksat

+0

ニース。 code_invertedは、後に続く%がない場合にのみ先頭の%で問題を解決することに注意してください(新しい先頭の%になります)。 :) – Ami

0

いくつかの考え:

  1. あなたが特定の条件に基づいて複数の小さなテーブルにテーブルを分割することができます。たとえば、IDにあるか、おそらくcodeであるか、その他のフィールドである可能性があります。それは基本的には、テーブル内のレコードの特定の種類を維持し、可能な場合はMySQL Partitioning

  2. を試してみてください別のテーブルに

  3. を異なる種類を分割することを意味します。古いエントリを削除したり、少なくともLIKEの

  4. 代わりに別のアーカイブテーブルに移動すると考えることがあり、SELECT *を実行しているよりも、

  5. むしろ正規表現検索用REGEXPを使用することを検討して、唯一の選択列を選択してみてくださいSELECT id, code, ...

  6. このクエリが、ユーザー入力値がcode列と比較され、結果がユーザーにエコーされるアプリケーション内の検索と多少関連しているかどうかはわかりません。しかし、そうであれば、検索クエリにオプションを追加することができます。たとえば、完全一致が必要かどうかをユーザーに問い合わせたり、一致などで開始する必要があります。

  7. 最初のポイントだったはずですが、テーブルに正しいインデックスがあると仮定します。

  8. さらに多くのクエリキャッシュを使用してみてください。これを使用する最善の方法は、各更新時にクエリキャッシュが消去されるため、テーブルを頻繁に更新しないようにすることです。だから、あまりアップデートは、それはMySQLは、その後迅速に結果

    を意味しますクエリ、キャッシュすることである可能性が高い

は、上記の情報がお役に立てば幸い!

+0

良い点がいくつかあります。明確にするために、REGEXPはパフォーマンスのためにLIKEより優れていません(おそらく悪化します)。クエリキャッシュは、検索が同一の場合にのみ役立ちます。 – Ami

関連する問題