目录
一.为什么查询速度会慢
查询的大致生命周期:从客户端,服务器,解析,生成执行计划,执行,返回客户端结果,其中执行可以认为是整个周期中最重要的阶段,这其中包括了大量为了检索数据到存储引擎的调用以及调用后的数据处理,包括排序,分组等。
二.慢查询基础,优化数据访问
查询性能底下的最基本的原因是访问的数据太多。对于低效的查询,我们发下通过下面两个步骤来分析总是很有效:
- 确认应用程序是否在检索大量超过需要的数据。这通常以为着访问了太多的行,也有可能是访问的太多的列。
- 确认MySQL服务器层是否在分析大量超过需要的数据行。
1.是否想数据库请求了不需要的数据
有些查询会请求超过实际需要的数据,然后这些多余的数据会被应用程序丢弃。这会给MySQL服务器带来额外的负担,并增加网络开销,消耗应用服务器的CPU和内存资源。
-
查询不需要的记录:
-
多表关联时返回全部列:
-
总是取出全部列:
2.MySQL是否在扫描额外的记录
在确定查询只返回需要的数据以后,接下来应该看看查询为了返回结果是否扫描了过多的数据。对于MySQL,最简单的衡量开销的三个指标如下:
- 响应时间
- 扫描的行数
- 返回的行数
这三个指标都记录到MySQL慢查询日志中。
- 响应时间:
- 扫描的行数和访问类型:
在explain语句中的type列反应了访问类型。访问类型有很多,从全表扫描,索引扫描,范围扫描,唯一索引查询,常数引用等。这里列的这些,速度是从慢到快,扫描的行数也是从小到大。
一般MySQL能够使用如下三种方式应用WHERE条件,从好到坏依次为:
- 在索引中使用WHERE条件来过滤不匹配的记录。这时在存储引擎层完成的
- 使用索引覆盖扫描(在Extra列中出现Using index)来返回记录,直接从索引中过滤不需要的记录并返回命中的结果。这是在MySQL服务器层完成的,但无须再回表查询记录。
- 从数据表中返回数据,然后过滤不满足条件的记录(在Extra列中出现Using Where)。这在MySQL服务器层完成,MySQL需要先从数据表读出数据
三.重构查询的方式
1.一个复杂的查询还是多个简单查询
MySQL从设计上让连接和断开连接都很轻量级,在返回一个小的查询结果方面很高效。现代网络速度比以前要快很多。如果一个复杂的查询很消耗时间的话,可以考虑分成几个小的查询。
2.切分查询
3.分解关联查询
很过高性能的应用都会对关联查询进行分解。简单地说,可以对每一个表进行一次单表查询,然后将结果在应用程序中进行关联。例如下面这个查询: