首页 > 代码库 > 高性能mysql 第6章 查询性能优化

高性能mysql 第6章 查询性能优化

在mysql的执行计划中:

 

id

id用来表示执行顺序,id相同的为一组,先执行id数字大的组,然后执行数字小的组。在id相同的一组内,顺序由上而下执行。

type

表示MySQL在表中找到所需行的方式,又称"访问类型",常见类型如下:

 技术分享

由左至右,由最差到最好。

ALL代表全表扫描,index代表索引全扫描,range索引范围扫描,ref是非唯一性索引扫描,常见的是作用在=的比较上,但是非唯一eq_ref:唯一性索引扫描。

possible_keys

指出MySQL能使用哪个索引在表中找到行,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用。注:如果使用覆盖索引扫描,此处为空。

key

显示MySQL在查询中实际使用的索引,若没有使用索引,显示为NULL

key_len

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度

rows:

表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数

ref:

暂时观察,只有当type是ref的时候这个才有值。一般是const或者列。

extra列:

use index:这里并不是表示使用了索引的意思。使用了索引可以通过key列来查看,而且key列显示了使用索引的名称。use index表示使用覆盖索引扫描。就是说,没有访问数据文件,所有的数据都是从索引文件中获取。

use where:这里并不是表示使用了where条件的意思,而是说服务层从存储引擎获取数据之后再进行where过滤。

Using index condition:表示使用索引条件去读取表中的数据,先扫描索引,然后根据索引指向的主健去读取对应的数据

Using filesort:使用了本地文件进行排序

Using temporary:使用了临时表

Impossible WHERE:出现在优化阶段,优化器根据表定义可以判断出where条件根本不可能成立,比如主健不可能为空

 Using join buffer (Block Nested Loop):mysql使用了优化过的nest loop算法,一次读取多个块.

 

查询缓存:

在解析一个sql之前,如果查询缓存是打开的,mysql会去检查这个查询(根据sql的hash作为key)是否存在缓存中,如果命中的话,那么这个sql将会在解析,生成执行计划之前返回结果。

查询优化器:

oracle使用基于cost的优化器。

可以使用last_query_cost来获取当前回话的上一个查询的cost:

  1. /*使用SQL_NO_CACHE禁用查询缓存*/
  2. select SQL_NO_CACHE count(*) from t_person;
  3. show status like ‘last_query_cost‘;

返回的结果10.499表示mysql查询优化器认为大概需要10个数据页的随机查找才能完成这个查询。这个结果是根据一系列的数据得出的,如每个表或者索引的页面个数,索引的基数,索引和数据行的长度,索引分布情况。

技术分享

由于统计信息的不准确,或者mysql本身的实现机制,有些情况下,计算的成本并不准确。

mysql能够处理的优化有:

  • 重新定义关联表的顺序
  • 将外连接转换为内连接
  • 使用等价变换规则 如(5=5 and a> 5)被改写成(a>5)
  • 优化count(),min(),max(),如对有索引的列取min只需要取b-tree中找第一个节点就可以了。
  • 预估并转化为常数表达式。不会改变的函数如上面提到的min函数会被转化为常数。

高性能mysql 第6章 查询性能优化