我有一个查询,即使表格应具有正确的索引,也需要90秒才能运行。我不明白为什么。
我正在使用mysql,而表则是innodb。
这是查询:
SELECT count(*)
FROM `following_lists` fl INNER JOIN users u
ON fl.user_uuid = u.user_uuid
WHERE fl.following_query_id = 1000010 AND u.status <= 2
我希望此查询能够从表following_lists
开始,根据位置获取大约4K记录,将这些记录通过其主键加入表users
,检查用户表中字段的值,然后返回结果记录的计数。为什么要花这么长时间?可能是因为我要加入的两个字段是char(40)而不是整数?
这些是所涉及的表及其索引:
CREATE TABLE `users` (
`user_uuid` CHAR(40) NOT NULL,
`status` TINYINT UNSIGNED NOT NULL,
...
PRIMARY KEY (`user_uuid`),
...
)
CREATE TABLE `following_lists` (
`following_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`following_query_id` INT UNSIGNED NOT NULL,
`user_uuid` CHAR(40) NOT NULL,
PRIMARY KEY (`following_id`),
KEY `query_id` (`following_query_id`),
KEY `user_uuid` (`user_uuid`)
)
这是解释查询的输出:
+----+-------------+-------+--------+--------------------+----------+---------+--------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+--------------------+----------+---------+--------------+------+-------------+
| 1 | SIMPLE | fl | ref | query_id,user_uuid | query_id | 4 | const | 3718 | |
| 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 160 | fl.user_uuid | 1 | Using index |
+----+-------------+-------+--------+--------------------+----------+---------+--------------+------+-------------+
更多详细信息:
表
following_lists
的表有大约25k行,但只有3718具有fl.following_query_id = 1000010
。表
users
的表约为160k行,但在加入中只能选择3718。只有40个记录符合这两个条件fl.following_query_id = 1000010 AND u.status <= 2
。即使我删除了条件
AND u.status <= 2
。
,查询也很慢。
"拥有正确的索引" - Dead放弃。
如果您使用的是Myisam,则不要。而是切换到Innodb。
您需要following_lists.id
吗?(following_query_id, user_uuid)
是唯一的吗?如果是这样,请将它们成为PRIMARY KEY
。
如果您不能做上述操作,请更改
KEY `query_id` (`following_query_id`)
to
INDEX(following_query_id, user_uuid)
UUIDs
效率低下,尤其是当不必要地声明的utf8mb4
或具有比必要大小更大的CHAR
时。更改为CHAR(36) CHARACTER SET ascii
。(请注意```160''中的" 160"。
更多地了解为什么UUID对性能不利:http://mysql.rjweb.org/doc.php/uuid
您有多少RAM?innodb_buffer_pool_size
的设置是什么?(听起来太低。)
有关索引的更多信息:http://mysql.rjweb.org/doc.php/index_cookbook_mysql