我遇到的问题是特定查询速度很慢。尽管一切都被大量索引,一些类似的查询工作正常并且使用了索引,但查询仍然很慢。我无法理解为什么,所以也许任何人都可以提供帮助。
仅为先决条件:基础表的写入速度无关紧要。该表包含约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 | |
+----------+------------------+------+-----+---------+----------------+
答案 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)
。