ORDER BY用于指定查询结果的排序规则,支持单列或多列的升序(ASC)或降序(DESC)排列,其性能受索引使用情况影响显著;若排序字段无合适索引,MySQL将执行filesort操作,导致性能下降;通过创建覆盖WHERE和ORDER BY的复合索引,可避免filesort,提升查询效率;当与LIMIT结合时,利用索引覆盖或延迟关联技术能有效减少排序数据量,尤其在深分页场景下,基于上一次查询的ID或时间戳进行条件过滤可大幅优化性能。

MySQL中的
ORDER BY
当你在MySQL中使用
ORDER BY
SELECT * FROM users ORDER BY registration_date DESC;
它的工作机制大致是这样的:
ORDER BY last_name, first_name
ASC
DESC
ORDER BY salary DESC, age ASC
ORDER BY
NULL
从我个人的经验来看,
ORDER BY
ORDER BY
谈到
ORDER BY
当MySQL执行
ORDER BY
filesort
filesort
何时会发生 filesort
ORDER BY
ORDER BY
col1 ASC, col2 ASC
col1 DESC, col2 ASC
col1 ASC, col2 DESC
WHERE
filesort
如何避免 filesort
ORDER BY
EXPLAIN
Using index
Using filesort
Using index
WHERE
ORDER BY
比如,你有一个查询
SELECT * FROM products WHERE category_id = 10 ORDER BY price DESC;
category_id
price
INDEX(category_id, price)
category_id = 10
price
filesort
但话说回来,索引也不是越多越好,它会增加写操作的开销,所以需要在读写之间找到一个平衡点。
ORDER BY
复合索引在
ORDER BY
filesort
一个复合索引,比如
INDEX(col1, col2, col3)
col1
col2
col3
col1
col1, col2
col1, col2, col3
复合索引如何满足 ORDER BY
ORDER BY
ORDER BY col1 ASC, col2 ASC, col3 ASC
ORDER BY col1 ASC
ORDER BY col1 ASC, col2 ASC
INDEX(col1, col2)
ORDER BY col1 ASC, col2 ASC
ORDER BY col1 DESC, col2 DESC
ORDER BY col1 ASC, col2 DESC
filesort
col1
col2
结合WHERE
WHERE
ORDER BY
SELECT * FROM orders WHERE customer_id = 123 ORDER BY order_date DESC;
INDEX(customer_id, order_date DESC)
DESC
但这里有一个“最左前缀原则”需要注意。如果你的查询条件没有用到复合索引的最左边列,那么这个索引可能就无法被充分利用来加速
WHERE
ORDER BY
INDEX(A, B, C)
WHERE B = 'x' ORDER BY C
所以,在设计复合索引时,需要仔细分析你的查询模式,将最常用的过滤条件放在索引的前面,然后将排序字段放在后面,并考虑排序方向。
ORDER BY
LIMIT
当
ORDER BY
LIMIT
LIMIT
核心思想:减少需要排序的数据量
LIMIT
索引覆盖 ORDER BY
LIMIT
ORDER BY
SELECT id, name FROM products ORDER BY price DESC LIMIT 10;
price
id
name
EXPLAIN
Using index
延迟关联(Delayed Join): 当你的
ORDER BY
SELECT
SELECT *
ORDER BY
LIMIT
users
registration_date
SELECT * FROM users ORDER BY registration_date DESC LIMIT 100, 10;
优化后的延迟关联:
SELECT u.*
FROM users u
JOIN (
SELECT id
FROM users
ORDER BY registration_date DESC
LIMIT 100, 10
) AS sub
ON u.id = sub.id;在这个优化版本中,子查询
sub
id
registration_date
registration_date
JOIN
id
避免 OFFSET
LIMIT offset, count
OFFSET
offset + count
count
OFFSET
LIMIT 100000, 10
-- 假设上次查询的最后一条记录ID是 last_id SELECT * FROM users WHERE id > last_id ORDER BY id ASC LIMIT 10;
这种方式可以避免
OFFSET
综合来看,
ORDER BY
LIMIT
EXPLAIN
以上就是mysql中order by语句如何排序的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号