为什么查询速度会慢 大量为了检索数据到存储引擎的调用,以及调用后的数据处理,包括排序和分组。
在完成这些任务的时候,查询需要在不同的地方花费时间,包括网络、CPU计算,生成统计信息和执行计划、锁等待等操作,尤其是向底层存储引擎检索数据的调用操作。优化和查询的目的就是减少和消除这些操作所花费的时间。
慢查询的基础:
-
优化数据访问
查询性能低下的最基本原因是访问的数据太多,大部分性能低下的查询可以通过减少访问的数据量的方式进行优化:
- 确认程序是否在检索大量超过需要的数据,这通常意味着访问太多行,但有时也可能是访问太多列。
- 确认MySQL服务器层是否在分析大量超过需求的数据
是否向数据库请求了不需要的数据 (2)多表关联时返回全部列 (3)重复查询相同的数据。
MySQL是否在扫描额外记录:在确定查询只返回需要的数据后,接下来应该看看为了需要的结果是是否扫描了过多的数据。对于MySQL,最简单的衡量查询开销三个指标如下:
- 响应时间
- 扫描行数
- 返回行数
这三个指标都会记录在MySQL慢日志中。
所以好的索引可以让查询使用适合的访问类型,尽可能地只扫描需要的数据行。如果发现查询需要扫描大量的数据但只返回少数的行,那么通常可以尝试以下的方式去优化它:
使用索引覆盖扫描,把所有需要用的列都放在索引中(比如多字段的聚合索引),这样存储引擎无须回表获取对应的行就能返回结果。
改变库表结构,例如使用单独的汇总表。
重写这个复杂的查询,让MySQL优化器能够以更优化的方式执行这个查询。
- 重构查询方式
一个复杂的查询还是多个简单的查询
切分查询
分解关联查询:可以对每个表进行一次单表查询,然后将结果在应用程序中关联。
可以对每个表进行一次单表查询,然后将结果在应用程序中关联。
好处:
让缓存效率更高。许多应用程序可以方便的缓存单表查询的结果集,另外,关联中的某个表发生了变化,那么就无法使用查询缓存了,拆分后,单表之间不受影响。
执行单个查询可以减少锁的竞争。
在应用层做关联,可以更容易对数据库拆分,更容易做到高性能和扩展性。
查询效率本身可能会有所提升。
可减少冗余记录的查询。在应用层做关联查询,意味着对某条记录应用只需要查询一次,而在数据库中做关联查询可能需要重复地访问一部分数据。
更进一步,这样做相当于在应用层实现了哈希关联,而不是MySQL的嵌套循环关联。
查询执行的基础
MySQL客户端/通信协议:半双工
查询缓存
查询优化处理
查询执行引擎
返回结果给客户端