MySQL中的简单重度索引表慢查询

时间:2016-01-08 12:42:51

标签: mysql performance mysql-slow-query-log

我遇到的问题是特定查询速度很慢。尽管一切都被大量索引,一些类似的查询工作正常并且使用了索引,但查询仍然很慢。我无法理解为什么,所以也许任何人都可以提供帮助。

仅为先决条件:基础表的写入速度无关紧要。该表包含约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可以处理数据就好了。

有人建议如何优化查询吗?任何建议,如果我可以使用更适合查询的不同索引?

为了比较,这两个类似的查询工作非常快

 --- 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    |                |
+----------+------------------+------+-----+---------+----------------+

1 个答案:

答案 0 :(得分:2)

请提供SHOW CREATE TABLE,它比DESCRIBE更具描述性!特别是,我看不到你有什么索引。

正如My index cookbook所解释的那样,使用任何字段'='启动索引,然后您有一次机会添加'范围'比较。您的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应该是最后的;其他列可以按任何顺序排列。也许你的一些索引处理了第三种情况?

  

它有很多索引可能太长而无法粘贴

可能大多数都未使用过。请注意,如果您还有INDEX(a),则无需INDEX(a,b)