mysql - 主键上的 MySQL 慢 ORDER BY ASC
问题描述
我遇到了带有 order by 的 SELECT 非常慢的问题。我有一个表,ENGINE=MyISAM,到目前为止它有 2600 万行。
当我跑
SELECT a.amount FROM billing WHERE user_id = 102458 ORDER BY id DESC LIMIT 100
一切正常,执行时间不到 0.5 秒
但是当我跑步时
SELECT a.amount FROM billing WHERE user_id = 102458 ORDER BY id LIMIT 100
它执行了超过 1 分钟。
id
是主键。
两个查询的 EXPLAIN 相同
ID | 选择类型 | 桌子 | 分区 | 类型 | 可能的键 | 钥匙 | key_len | 参考 | 行 | 过滤 | 额外的 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 简单的 | 一个 | 指数 | 用户哈希,用户 ID | 基本的 | 4 | 81351 | 0.61 | 使用哪里 |
MySQL 版本:5.7.32
更新:
如果指定order by
它不使用user_id
索引的问题。如果您查看 EXPLAIN 中的额外字段,您会看到 mysql 使用where
. 用户 102458 是一个新用户,因此该表中的所有条目都位于最后,这就是 DESC 工作速度快而 ASC 速度慢的原因。如果我将 user_id 更改为一些旧用户,ASC 开始快速工作,而 DESC 慢。
解决方案
它与索引的顺序有关,因为它已经按 DESC 排序,因此 ASC 需要一种需要时间的排序。
见(这适用于maysql 8,但我认为ot也适用于5.7
https://www.percona.com/blog/2016/10/20/mysql-8-0-descending-indexes-can-speedup-your-queries/#
您可以试验您的查询是在 user_id 上添加一个 INDEX 或为带有 ASC 的订单添加一个组合的 user_id,id ASC
推荐阅读
- gradle - 错误:无法解析“:app@debugAndroidTest/compileClasspath”的依赖关系:
- c++ - 在 C++ 中创建工具栏
- c++ - 在 C++ 中将多个变量设置为相同的值
- lambda - PySpark 1 缺少参数“y”
- javascript - 在 Node js 中使用 setTimout() 作为 Promise
- xcode - 机器学习模型错误预测
- python - 如何从没有标识符的属性中仅从网络中提取数字(通过美丽的汤)
- python - 将聚合函数应用于数据表列并返回值,而不是数据表
- javascript - Js按钮只能工作一次?
- python - 使用pyspark计算每行数据帧中的总值