查询优化
查询慢的原因#
- 网络
- CPU
- IO
- 上下文切换
- 系统调用
- 生成统计信息
- 锁等待时间
优化数据访问#
减少访问数据量的方式进行优化#
- 确认应用程序是否在检索大量超过需要的数据
- 确认mysql服务器层是否在分析大量超过需要的数据行
是否向数据库请求了不需要的数据#
- 查询不需要的记录
- 多表关联时返回全部列
- 总是取出全部列
- 重复查询相同的数据
执行过程的优化#
查询缓存(MySQL8之后移除)#
LRU淘汰策略
JoinBuffer(待更新)#
排序优化#
两次传输排序
- 第一次数据读取是将需要排序的字段读取出来,然后进行排序,第二次是将排好序的结果按照需要去读取数据行
- 这种方式效率比较低,原因是第二次读取数据的时候因为已经排好序
- 需要去读取所有记录而此时更多的是随机IO读取数据成本会比较高
- 两次传输的优势,在排序的时候存储尽可能少的数据,让排序缓冲区可以尽可能多的容纳行数来进行排序操作
单次传输排序
- 先读取查询所需要的所有列,然后再根据给定列进行排序,最后直接返回排序结果
- 此方式只需要一次顺序IO读取所有的数据,而无须任何的随机IO
- 问题在于查询的列特别多的时候,会占用大量的存储空间,无法存储大量的数据
排序的列的总大小超过 max_length_for_sort_data 定义的字节,mysql会选择双次排序,反之使用单次排序
优化特定类型的查询#
优化count()查询#
- count(1),count(*),count(col) 效率是一样的
- myisam的count函数,没有任何where条件的count(*)才是比较快的
- 使用近似值(hyperloglog)
- 复杂的优化,在实际操作的时候可以考虑使用索引覆盖扫描,或者增加汇总表,或者增加外部缓存系统
优化关联查询#
- 确保on或者using子句中的列上有索引,在创建索引的时候就要考虑到关联的顺序
- 确保任何的group by和order by中的表达式只涉及到一个表中的列,这样mysql才有可能使用索引来优化这个过程
优化子查询#
- 子查询的优化最重要的是尽可能使用关联查询代替
- 因为子查询结果会产生一个临时表
优化group by 和 distinct#
- 关联查询做分组,按某个列进行分组,采用查找表标识列分组查找效率高
select actor.first_name, actor.last_name,count(*) from film_actor inner join actor using(actor_id) group by actor.first_name, actor.last_name
select actor.first_name, actor.last_name,count(*) from film_actor inner join actor using(actor_id) group by actor.actor_id;
如果表标识列有重复字段上面这种写法会造成数据合并
using与on的区别,参考文章:https://www.cnblogs.com/YC-L/p/14461585.html
优化limit查询#
- 使用覆盖索引,而不是查询所有的列
explain select film_id,description from film order by title limit 50,5
explain select film.film_id,film.description from film inner join (select film_id from film order by title limit 50,5) as lim using(film_id);
覆盖索引,参考文章:
优化union查询#
- 如果没有规定过滤重复数据,就用union all
- union会合并重复数据,本质上是mysql在查询过程中使用了distinct
作者:BigBender
出处:https://www.cnblogs.com/BigBender/p/14461586.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!