0

特定のクエリが遅いという問題があります。すべてが大量にインデックス化されていますが、いくつかの同様のクエリは正常に機能し、インデックスが使用されていますが、クエリは依然として地獄のように遅い. 理由がわからないので、誰か助けてください。

前提条件として、基になるテーブルの書き込み速度は問題ではありません。テーブルには約 350 万のエントリが含まれていますが、MySQL で問題なく処理できるはずです。

遅いクエリは約 2 秒かかります

 SELECT DISTINCT t.`tag_3`  FROM `image_tags` t
     WHERE  t.`type` = 1 AND t.`category` LIKE "00%" AND tag_1 = "0"

--- DESCRIBE OUTPUT
--- The used index thirdtag is just an index defined as (type, category, tag_1, tag_3)
--- The actual result is 201 rows
+----+-------------+-------+- -----------------------+----------+---------+------+---------+-------------------------------------------+
| id | select_type | table | type  | possible_keys   | key      | key_len | ref  | rows    | Extra                                     |
+----+-------------+-------+-------+-----------------+----------+---------+------+---------+-------------------------------------------+
|  1 | SIMPLE      | t     | range | [... A LOT ...] | thirdtag | 31      | NULL | 1652861 | Using where; Using index; Using temporary |
+----+-------------+-------+-------+-----------------+----------+---------+------+---------+-------------------------------------------+

際立っている唯一のことは、関連する膨大な量の行です。この質問の最後に添付した2つの高速クエリと比較すると、文字通り唯一の違いです(少なくとも最初のクエリとは異なります)。ですから、おそらくそれが問題です。しかし、それがデータが私に与えられる方法なので、それを処理する必要があります。インデックスに関与していれば、mysqlはデータをうまく処理できると思いました。

クエリを最適化する方法について誰か提案がありますか? クエリにより適した別のインデックスを使用できるとしたら、何か提案はありますか?

比較のために、これら 2 つの同様のクエリは非常に高速に動作します

 --- just a longer category string resulting in fewer results
 SELECT DISTINCT t.`tag_3`  FROM `image_tags` t
     WHERE  t.`type` = 1 AND t.`category` LIKE "0000%" AND tag_1 = "0"

 --- and additional where clause
 SELECT DISTINCT t.`tag_3`  FROM `image_tags` t
     WHERE  t.`type` = 1 AND t.`category` LIKE "00%" AND tag_1 = "0" and tag_2 = ""

テーブル (貼り付けるには長すぎると思われる多くのインデックスがあります)。

+----------+------------------+------+-----+---------+----------------+
| Field    | Type             | Null | Key | Default | Extra          |
+----------+------------------+------+-----+---------+----------------+
| id       | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| image    | char(8)          | NO   | MUL | NULL    |                |
| category | varchar(6)       | YES  | MUL | NULL    |                |
| type     | tinyint(1)       | NO   | MUL | NULL    |                |
| tag_1    | char(3)          | NO   | MUL | NULL    |                |
| tag_2    | char(3)          | NO   | MUL | NULL    |                |
| tag_3    | char(3)          | NO   | MUL | NULL    |                |
| tag_4    | char(3)          | NO   | MUL | NULL    |                |
| tag_5    | char(3)          | NO   | MUL | NULL    |                |
| tag_6    | char(3)          | NO   | MUL | NULL    |                |
+----------+------------------+------+-----+---------+----------------+
4

1 に答える 1

2

を提供SHOW CREATE TABLEしてくださいDESCRIBE。特に、あなたが持っているインデックスがわかりません。

My index cookbookで説明されているように、「=」である任意のフィールドでインデックスを開始すると、「範囲」比較を追加するチャンスが 1 回得られます。あなたcategoryは範囲なので、

WHERE  t.`type` = 1 AND t.`category` LIKE "00%" AND tag_1 = "0"

category通り過ぎない

INDEX(type, category, tag_1, tag_3)

3 つのクエリの場合、これらは最適なインデックスです。

INDEX(type, tag_1, category)
INDEX(type, tag_1, category)
INDEX(type, tag_1, tag_2, category)

category最後にする必要があります。他の列は任意の順序にすることができます。おそらく、あなたのインデックスの 1 つが 3 番目のケースを処理したのでしょうか?

おそらく貼り付けるには長すぎる多くのインデックスがあります

おそらくほとんどが未使用です。INDEX(a)もお持ちの場合は不要ですのでご注意くださいINDEX(a,b)

于 2016-01-08T18:32:15.593 に答える