持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
面试官:查询数据的时候可以做哪些优化?
查询慢的原因
- 网络
- CPU
- IO
- 上下文切换
- 系统调用
- 生成统计时间
- 锁等待时间
优化数据访问
查询性能低下的主要原因是访问的数据太多,某些查询不可避免的需要筛选大量的数据。我们可以通过减少访问数据量的方式进行优化。
减少访问量
- 确认应用程序是否在检索大量超过需要的数据。
- 确认MySQL服务器层是否在分析大量超过需要的数据行。
是否向数据库请求了不需要的数据
- 查询不需要的记录。
- 多表关联时返回全部列。
- 总是取出全部列。
- 重复查询相同的数据。
执行过程的优化
查询优化器
统计信息
- 每个表或索引的页面个数。
- 索引的基数。
- 索引和数据行的长度。
- 索引的分布情况。
MySQL选择错误执行计划的原因
- 统计信息不准确。
- 执行计划成本估算不等同于实际执行的成本。
- MySQL的最优可能跟你想的不一样。
- MySQL不考虑其他并发执行的查询。
- MySQL不考虑不受其控制的操作成本。
优化器的优化策略
- 静态优化:直接对解析树进行分析并完成优化。
- 动态优化:与查询的上下文有关,也可能跟取值、索引对应的行数有关。
- MySQL对查询的静态优化只有一次,但对动态优化每次执行时都要重新评估。
优化器的优化类型
- 重新定义关联表的顺序。
- 将外连接转化为内连接,内连接效率比外连接更高。
- 使用等价变换规则,MySQL可以使用一些等价变换来简化并规划表达式。
- 优化count(),min(),max()。
- 预估并转化为常数表达式,当MySQL检测到一个表达式可以转化为常数时,就会一直把该表达式做为常数处理。
- 索引覆盖扫描,当索引中的列包含所有查询中需要使用的列时,可以使用覆盖索引。
- 子查询优化。
- 等值传播。
优化特定类型的查询
优化count()查询
- 总有人认为MyISAM的count函数比较快,但这是有前提条件的,只有不带任何where条件的count()才是比较快的。
- 使用近似值。
- 更复杂的优化。
优化关联查询
- 确保on或using子句中的列上有索引,在创建索引的时候就要考虑到关联的顺序。
- 确保任何的groupBy和orderBy中的表达式只涉及到表中的一个列,这样MySQL才有可能使用索引来优化这个过程。
优化limit分页
最简单的办法是尽可能使用覆盖索引,而不是查询全部的列。
优化union查询
除非确实需要服务器消除重复的行,否则一定要使用union all,因为没有all关键字,MySQL会在查询的时候给临时表加上distinct关键字,这个代价很高。