MySQL中简单的重索引表慢速查询
我遇到了一个特别的查询速度慢的问题。尽管所有内容都被大量索引,一些类似的查询工作正常,并且使用了索引,但查询仍然非常慢。我不明白为什么,所以也许任何人都可以帮忙 仅针对先决条件:基础表的写入速度并不重要。这个表包含350万个条目,但我想MySQL应该可以很好地处理这个问题 缓慢的查询大约需要2秒MySQL中简单的重索引表慢速查询,mysql,performance,mysql-slow-query-log,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%"
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 |
+----+-------------+-------+-------+-----------------+----------+---------+------+---------+-------------------------------------------+
唯一突出的是涉及的大量争吵。如果你与我附在问题末尾的两个快速查询相比较,这是唯一不同的地方(至少与第一个不同)。所以很可能这就是问题所在。但是数据就是这样给我的,所以我需要处理这个问题。我认为如果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 = ""
表(它有很多索引,可能太长而无法粘贴)
请提供
SHOW CREATE TABLE
,它比description
更具描述性!特别是,我看不到您有什么索引
如前所述,从任何“=”字段开始索引,然后您就有机会添加“范围”比较。您的类别是一个范围,因此
WHERE t.`type` = 1 AND t.`category` LIKE "00%" AND tag_1 = "0"
未通过中的类别
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)
类别
应该是最后一个;其他列可以是任意顺序。也许你的某个索引处理了第三个案例
它有很多索引,可能太长而无法粘贴
可能大部分都没有用过。请记住,索引(a)
是不必要的,如果您还有索引(a,b)
标记3上有单独的索引吗?我认为,如果按此顺序在(tag_1、category、type、tag_3)上创建复合索引,查询速度会更快。然后DISTINCT可以从索引中获得结果,而不必从表中获取结果。但我会尝试重新排序。确实对指数顺序做了一些调整,但结果却更糟。不知道我是否尝试过你的订单,尽管+1分。将tag_3
作为第四列,即(type,tag_1,category,tag_3)
将为查询创建覆盖索引。使用该索引,我们希望解释输出在额外的列中显示“使用索引”。这意味着可以完全从索引页满足查询,而不需要对基础表中的数据页进行任何查找。(对于此查询,覆盖索引可能是更好的索引。)此外,更改索引中列type
和tag_1
的顺序也可能有意义。根据基数的不同,这可能会有一点不同。还有一种可能性是,在索引中将tag_3
重新定位到category
之前,会使MySQL避免“sort unique”操作,否则需要执行该操作才能获得“distinct”列表。e、 g.(标签1,类型,标签3,类别)
。如果执行计划使用该索引,并且解释输出仍然在Extra
列中显示“Using filesort”,那么该索引将毫无意义(对于此查询)。但是如果执行计划避免“Using filesort”操作,那么这可能是查询的更好索引。
INDEX(type, tag_1, category)
INDEX(type, tag_1, category)
INDEX(type, tag_1, tag_2, category)