**优化**
查询优化、索引优化、库表结构优化
# 6.2 慢查询基础:优化数据访问
1.确认应用程序是否在检索大量超过需要的数据。这通常意味着访问了太多的行,但有时候也可能是访问了太多的列。
2.确认MySQL服务器层是否分析大量超过需要的数据行
**查询不需要的记录**
例如在新闻网站中取出100条记录,但是只是在页面上显示前面10条)。他们认为MySQL会执行查询,并只返回他们需要的10条数据,然后停止查询。实际情况是MySQL会查询出全部的结果集,客户端的应用程序会接收全部的结果集数据,然后抛弃其中大部分数据。最简单有效的解决方法就是在这样的查询后面加上LIMIT。
**多表关联时返回全部列**
查询所有在电影Academy Dinosaur中出现的演员
比如:
![](https://box.kancloud.cn/90ea914764d78dcf6dad3e21307d61f8_620x120.png)
应该:
![](https://box.kancloud.cn/b401d83329adc1bfa68633f11fd73aa0_648x49.png)
如果应用程序使用了某种缓存机制,获取并缓存所有的列的查询,相比多个独立的只获取部分列的查询可能就更有好处。
**重复查询相同的数据**
比较好的方案是,当初次查询的时候将这个数据缓存起来,需要的时候从缓存中取出,这样性能显然会更好
## 6.2.2 MySQL是否在扫描额外的记录
衡量查询开销:
![](https://box.kancloud.cn/6c2dc3a592b8121e02c8bd6ab92f5d39_141x122.png)
这三个指标都会记录到MySQL的慢日志中,所以检查慢日志记录是找出扫描行数过多的查询的好办法。
**响应时间:**
见书
**扫描的行数和返回的行数**
理想情况下扫描的行数和返回的行数应该是相同的。但实际情况中这种“美事”并不多。例如在做一个关联查询时,服务器必须要扫描多行才能生成结果集中的一行。扫描的行数对返回的行数的比率通常很小
在EXPLAIN语句中的type列反应了访问类型,扫描表、扫描索引、范围访问和单值访问,速度从慢到快。
一般MySQL能够使用如下三种方式应用WHERE条件,从好到坏依次为:
•在索引中使用WHERE条件来过滤不匹配的记录。这是在存储引擎层完成的。
•使用索引覆盖扫描(在Extra列中出现了Using index)来返回记录,直接从索引中过滤不需要的记录并返回命中的结果。这是在MySQL服务器层完成的,但无须再回表查询记录。
•从数据表中返回数据,然后过滤不满足条件的记录(在Extra列中出现Using Where)。这在MySQL服务器层完成,MySQL需要先从数据表读出记录然后过滤。
*****
type列
MySQL找到数据行的方式,即访问类型。效率从最差到最好的顺序如下:
ALL
全表扫描,没有用到任何的索引,这是一种非常原始的查找方法,非常的耗时二号抵消。
index
这种类型只是另一种形式的全部扫描,只不过它的扫描顺序是按照索引的顺序,然后根据索引回表取数据。和All相比,他们都是取得了全表的数据,而且index要先读索引再回表取数据。
如果连接类型为type,而且extra列中的值为‘Using index’,那么称这种情况为索引覆盖。
rang
rang指的是有范围的索引扫描,相交于index的全索引扫描,它有范围限制,因此要优于index。
它是基于索引的,表示WHERE条件中对索引列使用了BETWEEN AND、>、 <、 IN、OR。
ref
查找条件使用索引而且不为主键或unique。表示虽然使用了索引,但该索引列的值不唯一,有重复。这样即使使用索引找到了第一条数据,仍然需要进行目标值附近的小范围扫描,但它的好处是不用全表扫描。
-ref_eq
进行精确查询,结果集唯一,表示使用了主键或唯一性索引查找的情况。
const,system
当MySQL能对查询部分进行优化,并且转换为一个常量。比如,where条件使用主键查询。
extra列
这一列包含的是不在其他列显示的额外信息。
using index
这个说明MySQL使用覆盖索引,避免了回表操作,效率不错。
using where
服务器在存储引擎收到行后会进行过滤。即会根据查询条件过滤结果集。
这表示服务器在存储引擎返回行以后再应用WHERE过滤条件。
using file sort
表示排序的时候没有用到索引,不得不采取其他方式排序。排序方法有内存排序,在临时文件排,采用双路排序法,或者是采用整行排序等,using file sort并没有说是那些排序方法。
using temporay
表示用到了一张临时表,至于临时表是在内存中还是在磁盘上就不知道了。
*****