本文主要是介绍高性能MySQL——查询性能优化,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
慢查询基础:优化数据访问
查询性能低下的基本原因就是:访问的数据太多了。这并不是单单指你的SQL语句最终需要获取的行数太多了,一个坏的数据库设计可能在你需要访问10行数据时扫描上万行数据。所以你需要从两方面考虑:
- 确认应用程序是否正在检索大量超过需要的数据
- 确认MySQL服务器层是否在分析大量超过需要的数据行
1. 是否向数据库请求了不需要的数据
- 查询不需要的记录
- 多表关联时返回全部列
- 总是取出全部列
- 重复查询相同数据
关键问题在于,你的每次查询,数据库是否返回了你需要的数据之外的数据。但如果你的应用层采用了缓存设计,那么向数据库请求预期之外的数据也情有可原。
2. MySQL是否在扫描额外的记录
这一点,我们可以通过分析一个查询的开销来判断,有三个可考量的参数:
- 响应时间
- 扫描的行数
- 返回的行数
响应时间
响应时间 = 排队时间 + 服务时间,排队时间是指服务器已经收到了一个查询请求但还在等待必要的资源,如锁、IO。
可以通过估算当前SQL语句要查询的索引,估计要多少次随机IO,得到一个估计响应时间来与实际的作比较。
扫描行数和返回行数
在关联查询、排序、多表连接时可能需要扫描多行才能返回一行,在全表扫描中,甚至扫描了整个表才返回一行数据。
扫描行数和实际返回行数的比值应该尽量小,一般在1:1到10:1之间。
扫描的行数和访问类型
EXPLAIN
语句中的type
列反映了访问类型,有这几种:全表扫描、索引扫描、范围扫描、唯一索引查询、常数引用。速度从慢到快,扫描行数从大到小。
对于WHERE条件的过滤,MySQL中有从好到坏这么几种情况:
- 在索引中直接就能过滤掉WHERE条件,一般是索引等值查询(type=ref|eq_ref),索引的范围查询(type=range),高版本中的ICP优化查询(Extra=Using index condition)。这种情况下,MySQL服务器层不需要再次使用WHERE条件检查,存储引擎所返回的就是最终返回给客户端的行。
- 使用索引覆盖扫描(索引能覆盖查询的行和条件中的行),无需再次查询表获取行,但是需要服务器通过Where来过滤掉不需要的索引项。(Extra中包含Using index和Using where)
- 需要从行中拉取数据,并且从服务器层中应用WHERE条件,这代表索引无法覆盖(或者压根没索引)。
讲实话,我昨天早上就读到这里了,但是我没咋懂,因为对MySQL的EXPLAIN返回结果和索引查询机制不太了解,于是我去读了下官方文档并写了几篇文章。先说,我自己觉得我写的有些混乱并且有些地方还是模糊,没有吃透,不过如果看官方文档感觉哪里不太懂,我这两篇也是个参考。
- MySQL——Explain中的部分字段含义
- MySQL ICP(索引条件推送)和延迟加载
总之,一个好的索引能让查询时MySQL以最少的扫描行数获得需要的行。
优化方式:
- 尽量使用索引覆盖扫描
- 改变库表结构,加入一些汇总表,而不是查询原表
- 重写复杂的查询,让MySQL优化器能以更加优化的方式执行这个查询
重构查询的方式
这篇关于高性能MySQL——查询性能优化的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!