学习文章
- 慢查询优化 (yuque.com)
- MySQL中什么情况下会出现索引失效?如何排查索引失效?_如何定位索引失效-CSDN博客
- 五分钟搞懂MySQL索引下推大家好,我是老三,分享一个小知识点。面试时候问到索引,常常会顺嘴问一句索引下推。给我五分钟, - 掘金 (juejin.cn)
- MySQL索引可能失效之or、is null、is not null、不等于(!=,<>)、联合索引_!= 索引不失效-CSDN博客
-
优化方式
- 先通过explain执行计划检查具体执行情况
- 检查是否使用了索引
- 避免索引失效的情况
- 深分页优化
- 内嵌
SELECT
可以更高效地定位到目标数据,避免回表查询,减少了查询开销。
- 内嵌
Order By优化
ORDER BY
是一个成本较高的操作,因为排序不仅涉及大量的数据处理,还可能需要创建临时表并进行额外的 I/O 操作。为了更生动地理解它为什么会带来高成本,可以从以下几个方面来说明:
- 全字段排序:当我们执行
ORDER BY
时,如果排序字段没有索引,MySQL 需要对所有符合条件的记录进行排序。举个例子,想象一下你有一大堆纸,每张纸上写了一个数字,而这些纸张是乱序的。你需要先找到所有符合条件的纸张(比如数字小于 100),然后将这些纸按从小到大的顺序重新排列。
在数据库中,MySQL 会将这些需要排序的记录放入 sort_buffer
(一种内存空间),并在内存中对这些数据进行排序。如果数据量很大,内存不够用,就必须将部分数据写到磁盘,这大大增加了处理时间和资源消耗。
- 基于
rowid
的排序:当查询返回的字段不在索引中,MySQL 可能会用rowid
(指向表中具体记录的行号)来进行排序。MySQL 首先会在排序时建立一个临时表,只记录每条记录的rowid
和排序字段。排序完成后,它需要“回表”——根据rowid
去主表中找到完整的数据。
举个例子,想象你想根据一个属性(比如年龄)对员工名单排序,但你只拿到了员工的工号(rowid
)。你先根据工号把他们的年龄排好序,然后再一一找到对应的员工完整信息。这个过程就是所谓的“回表操作”,它增加了额外的 I/O 开销。
-
临时表和 I/O 开销:排序的过程中,尤其是当需要处理大量数据时,MySQL 可能需要创建临时表,临时表的创建与销毁都会消耗资源。此外,排序可能会超过内存限制,将部分数据写到磁盘再读回,进一步增加了时间和硬盘 I/O(输入/输出)成本。
-
索引的作用:如果你给
ORDER BY
的字段添加了索引,就像是将一堆无序的纸张提前按顺序排好了放在抽屉里。这样当你需要排序时,MySQL 只需按顺序从这个“有序的抽屉”里拿出数据,而不需要再重新排序。这样就节省了大量的时间和资源。 -
组合索引的顺序:当
ORDER BY
涉及多个字段时,索引的设计很关键。如果索引的顺序和ORDER BY
中字段的顺序一致,MySQL 可以直接利用索引的顺序来进行排序。如果索引顺序不匹配,MySQL 就需要额外排序。
总结:
排序耗时的根本原因是数据量大时,内存和磁盘的I/O开销增加。如果排序的字段有索引,MySQL 可以直接利用这些有序的数据,减少不必要的资源消耗,否则排序会涉及到临时表、回表操作等复杂过程。