1

私は比較的大きなテーブル (5,208,387 行、400 MB データ/670 MB インデックス) を持っています。検索に使用するすべての列はインデックスです。 nameおよびtypeVARCHAR(255) BTREE INDEX でsdateあり、タイムスタンプを含む INTEGER 列です。

いくつかの問題を理解できません。まず、このクエリは非常に遅いです (5 秒):

SELECT *
FROM `mytable`
WHERE `name`  LIKE 'hello%my%big%text%thing%'
AND `type` LIKE '%'
ORDER BY `sdate` DESC LIMIT 3

上記について説明します。

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE      mytable range   name        name    257 NULL    5191    Using where

これは非常に高速ですが(5ミリ秒):

SELECT *
FROM `mytable`
WHERE `name`  LIKE 'hello.my%big%text%thing%'
AND `type` LIKE '%'
ORDER BY `sdate` DESC LIMIT 3

上記について説明します。

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE      mytable range   name        name    257 NULL    204 Using where

スキャンされる行の量の違いは、インデックスのために理にかなっていますが、5k のインデックス付きの行に 5 秒かかるのは多すぎるようです。

また、name代わりにsdate並べ替えると、クエリが非常に高速になりますが、タイムスタンプで並べ替える必要があります。

私が理解していない2番目のことは、最後の列をインデックスに追加する前に、データベースには1.4GBのインデックスがあり、OPTIMIZE/REPAIRを実行した後のサイズはわずか670MBであることです。

4

1 に答える 1

1

問題は、最初の文字列の%の部分だけがインデックスを利用できることです。残りのlike文字列は、一致するすべての行を処理する必要があるhello%hello.my%、1つの助けを借りずに処理する必要があります。また、別の列で並べ替えてから使用するインデックスを並べ替えるには、おそらく2回目のパス、または少なくともソート済みのインデックスではなくスキャンが必要です。パフォーマンスを向上させるためのオプション(互いに独立して実装できます)は次のとおりです。

  1. 名前列に全文索引を使用し、' sMATCH() AGAINST()ではなく検索を使用します。LIKE%
  2. sdateインデックスにtoを追加すると、combined (name,sdate)並べ替えを非常に高速化できます。
于 2012-06-27T14:16:48.133 に答える