0

我遇到了特定查询速度慢的问题。尽管所有内容都被大量索引,一些类似的查询工作正常并且使用了索引,但查询仍然慢得要命。我不明白为什么,所以也许任何人都可以提供帮助。

只是为了先决条件:底层表的写入速度无关紧要。该表包含约 350 万个条目,但我猜 MySQL 应该可以处理得很好。

查询慢的大约需要 2s

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

1 回答 1

2

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

正如我的索引食谱所解释的,以任何字段为“=”的索引开始,然后您有机会添加一个“范围”比较。你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).

于 2016-01-08T18:32:15.593 回答