4

我有一张表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 秒),但不像使用索引主键进行排序和限制时那样的 2 分钟profilecomment_id

你知道有什么问题吗?可能是损坏的索引?如何发现?怎么修?ANALYZE TABLE 显示消息“ok”。

解释tb_profilecomments :

解释表命令

显示创建表tb_profilecomments

显示创建表命令

结果EXPLAIN SELECT * FROM tb_profilecomments WHERE profilecomment_user_id=6430 ORDER BY profilecomment_id DESC LIMIT 1, 5

解释选择命令

4

2 回答 2

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和。(否则有filesort,tmp table等,才可以应用。)GROUP BYORDER BYLIMITLIMIT

对于超慢查询,请提供EXPLAIN SELECT ...和(如果可能)EXPLAIN FORMAT=JSON SELECT ...,。

不要在 InnoDB 表上删除PRIMARY KEY这是非常需要的。(好的,如果要更换它,请将其丢弃。)

于 2015-08-30T00:21:07.337 回答
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 & http://sqlfiddle.com/#!9/5c50d/1

旧版本忽略DESC并保持秩序ASC。详情请参考以下网址:

http://dev.mysql.com/doc/refman/5.5/en/create-index.html

于 2015-08-29T11:21:07.397 回答