先分析一下查询慢的原因:
- 网络
- IO
- CPU
- 上下文调用
- 系统调用
- 生成统计信息
- 锁等待
以上问题都是sql 查询中 出现慢的原因。
优化数据访问
- 查询效率低下的主要问题是访问的数据太多。某些查询不可避免的筛选了大量的数据,我们可以减少访问数量进行优化
1.确认应用程序是否在检索大量超过需要的数据
2.确认mysql是否在检索超过需要的数据行 - 是否向数据库查询了不需要的数据
1.查询不需要的数据
2.多表关联时返回了不需要的列
3.总是取出全部列
4.总是重复的查询相同的数据
执行过程的优化
- 查询缓存
在解析一个查询之前,如果查询缓存是打开的。如果命中了这个查询,查询会先检验一下用户权限,如果用户权限没有问题,会直接返回给客户端,并跳过所有检验过程 - 查询优化处理
1.语法解析和预处理
2.查询优化器
很多情况下mysql 会 选择错误的执行计划,原因如下:
1.信息统计不准确
2.执行计划的成本不等同于执行计划的成本
3.mysql 的最优和你想象得不一样
4.mysql 不考虑并发情况
5.mysql 不受其控制得操作成本
优化器的优化策略
1.静态优化
直接对解析进行优化,并完成优化
2.动态优化
与查询的上下文有关,也可能和取值,索引对应的行数有关
静态优化只需要一次。
动态优化需要每次查询重新评估
优化器的优化类型:
重新定义关联表的顺序
将外连接转化成内连接,内连接效率高于外连接
优化 count().max().min()
覆盖所有
子查询优化
等值传播
优化特定类型的查询
- 优化count查询
myisam 的 count 是用一个变量来存储的,没有任何条件的count() 效率高 直接返回。
- 优化关联查询
确保 on 和 using 的子查询上有索引,在创建的时候要考虑到关联顺序
确保任何 order by 和 group by 只涉及到一张表中的列,这样 mysql 才可以优化这个过程
- 优化子查询
子查询建议尽量使用 关联查询代替
- 优化limit 分页
尽量使用索引覆盖,而不是查询所有的列
例:
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 在查询的时候 会 在临时表 加上 distinct ,代价比较高