我有一张表 tb_profilecomments :
4,3 GiB - 总计800万行 - InnoDB
有3个索引:
我运行的查询很简单:
SELECT *
FROM tb_profilecomments
WHERE profilecomment_user_id=6430
ORDER BY profilecomment_id DESC
在不到1秒(16.000+行)内获得结果。
当我现在向查询添加LIMIT 1, 5
时,我需要等待超过2分钟才能得到结果。
不知道mysql背景中发生了什么,为什么它会大大减慢查询速度。
当我从查询中删除ORDER BY
或LIMIT
时,一切都很好。
按非索引profilecomment_date
列对其进行排序时,它会慢(7秒),但不会像使用索引主键profilecomment_id
进行排序和限制时那样2分钟。
你知道什么是错的吗?破碎的指数可能吗?怎么找出来?怎么修? ANALYZE TABLE说消息" ok"。
EXPLAIN tb_profilecomments :
显示创建表 tb_profilecomments :
结果EXPLAIN SELECT * FROM tb_profilecomments WHERE profilecomment_user_id=6430 ORDER BY profilecomment_id DESC LIMIT 1, 5
:
答案 0 :(得分:1)
索引中的行非常有序。仅ASC
。甚至5.7手册页也说
index_col_name规范可以以ASC或DESC结尾。这些关键字允许用于将来的扩展,以指定升序或降序索引值存储。目前,他们被解析但被忽略;索引值始终按升序存储。
MySQL一直有这种限制。 (升级无济于事。)
但是......这并不能阻止代码以DESC
顺序提供结果。
也就是说,MySQL没有DESC索引的缺点很少。以下是一个重要的案例:ORDER BY x ASC, y DESC
。不能构建INDEX
(在MySQL中)来有效地处理它。
查询的最佳索引是
INDEX(user_id, comment_id);
user_id
将用于WHERE user_id = _constant_
,然后会以相反的顺序扫描comment_id
以获取您想要的行。有或没有LIMIT
。
但是......索引必须在WHERE
之前处理<{1}},GROUP BY
和ORDER BY
的所有短路执行。 (否则,在应用LIMIT
之前,有一个filesort,tmp表等。)
对于超慢查询,请提供LIMIT
和(如果可能)EXPLAIN SELECT ...
。
不将EXPLAIN FORMAT=JSON SELECT ...
放在InnoDB表上!这是非常需要的。 (好的,如果要更换它,请将其丢弃。)
答案 1 :(得分:0)
按列递减顺序在列profilecomment_id
上创建索引。
语法格式:
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
[index_type]
ON tbl_name (index_col_name,...)
[index_type]
index_col_name:
col_name [(length)] [ASC | DESC]
index_type:
USING {BTREE | HASH}
示例示例:
create table t1(id int(9),name varchar(20),
[UNIQUE] KEY (id DESC));
DESC命令不适用于主键。但它适用于UNIQUE or normal index
。您可以通过以下链接进行验证:
http://sqlfiddle.com/#!9/ddf95/1&amp;
http://sqlfiddle.com/#!9/5c50d/1
旧版本忽略DESC
并保留订单ASC
。
详情请参阅以下网址: