目录:
- 为什么查询速度慢
- 优化数据访问
- 重构查询方式
- 查询缓存
- 特定类型的优化
为什么查询速度慢
如果我们把查询看做是一个任务的话,那么它肯定是由多个子任务构成。
也就是说如果要优化查询的速度的话,无非就是优化其子任务,要么消除其中一些子任务,要么减少子任务的执行次数,要么让子任务执行的更快。
优化数据访问
归根结底性能低下的基本原因就是数据量大,且某些查询无法避免需要筛选大量数据,故大部分性能低下的SQL都可以通过减少访问量的方式进行优化。
对于低效的SQL往往可以通过以下两种方式来优化:
- 确认程序是否检索了不需要的数据(多余的行、多余的列)。
- 查询了不需要的记录
- 多表关联时返回了全部了列
- 总是获取全部的列
- 重复查询相同的数据
- 确认MySQL服务器的扫描行是否远超实际返回行。
重构查询方式
1、选择一个复杂的查询还是多个简单的查询。
2、切分查询(LIMIT)。
3、分解关联查询。
查询缓存
1、如何判断查询是否命中
MySQL通过计算SQL的Hash值来缓存SQL结果,此中任何字符(例如:空格、注释)的不同都会导致计算的Hash值不一样,导致缓存不能命中。
当包含如NOW()、CURRENT_DATA()之类的函数,或用户自定义函数、自定义变量、临时表等都不会缓存。
注意:MySQL的查询缓存虽然能带来性能的提示,但同时也会降低读写的性能。
———————————————————————————————————————————————————————
2、查询缓存如何使用内存
除了缓存一些查询的结果外,还需要缓存一些相关的维护数据(大约40KB左右),如哪些内存可用、哪些已用、哪些是映射关系等。
———————————————————————————————————————————————————————
3、查询缓存如何分配内存
内存分配是非常复杂的,这里简述下最简单的一种。
初始内存 >>> 一部分 >>> 不够加内存 >>> 释放多余内存
———————————————————————————————————————————————————————
4、分析和配置查询缓存流程图
———————————————————————————————————————————————————————
5、查询缓存的优化
- 用多个小表替代一个大表对查询缓存有好处。
- 批量写入时只需要做一次缓存失效,相比单条写入效率更好。
- 因为缓存空间太大,在过期操作的时候可能会导致服务器僵死。
- 无法在数据库或者表级别控制查询缓存,但是可以通过SQL_CACHE和SQL_NO_CACHE来控制某个SELECT语句是否需要进行缓存。
- 对写密集型应用来说,直接禁用查询缓存性能更好。
- 如果不想所有查询都进入缓存,可以设置query_cache_type为DEMAND。
特定类型的优化
1、优化COUNT()查询
-
使用近似值:执行计划中的值。
- 汇总表。
2、优化关联查询
- 确保on或者USING子句中的列上有索引。
- 在创建索引的时候要考虑到关联的顺序。
- 关联查询也可以使用组合索引。
3、优化GROUP BY
-
如果需要对关联查询做分组,那通常采用查找表的标识列分组的效率会比其他列更高。
4、优化LIMIT分页
- 尽可能的使用索引覆盖扫描,而不是查询所有的列,然后根据需要做一次关联操作再返回所需的列。
- "延迟关联"将大大提升查询效率,使MySQL扫描尽可能少的页,获取需要访问的记录后再根据关联列回原表查询需要的所有列。
5、优化UNION查询
- UNION与UNION ALL的差别,union all不再创建临时表,这样在联合查询时会减少I/O开销。