1、优化SQL步骤
1.1、查看SQL执行效率
查看当前连接的执行情况:
--查看当前会话
mysql> show status like 'Com_______';
--查看全局
mysql> show status like 'Com_______';
--查看innodb执行情况:
mysql> show global status like 'innodb_rows_%';
1.2、定位低效的SQL语句
可以通过以下两种方式定位执行效率较低的SQL语句。
- 慢查询日志:通过慢查询日志定位那些执行效率较低的SQL语句,用–log-slow-queries[=file_name]选项启动时,mysqld写一个包含所有执行时间超过long_query_time秒的SQL语句的日志文件。
- show processlist:慢查询日志在查询结束以后才记录,所以在应用反映执行效率出现问题的时候查询慢查询日志并不能定位问题,可以使用show processlist命令查看当前MYSQL在进行的线程,包括线程的状态、是否锁表等,可以实时地查看SQL的执行情况,同时对一些锁表操作进行优化。
mysql> show processlist;字段解释
1)id列,用户登录mysql时,系统分配的”connection_id”,可以使用函数connection_id()查看
2)user列,显示当前用户,如果不是root,这个命令就只显示用户权限范围的SQL语句
3)host列,显示这个语句是从哪个ip的哪个端口上发的,可以用来跟踪出现问题语句的用户
4)db列,显示这个进程目前连接的是哪个数据库
5)command列,显示当前连接的执行的命令,一般取值为休眠(sleep),查询(query),连接(connect)等
6)time列,显示这个状态持续的时间,单位是秒
7)state列,显示使用当前连接的SQL语句的状态,很重要的列,state描述的是语句执行中的某个状态,一个SQL语句,以查询为例,可能需要经过copying to tmp table、sorting result、sending data等状态才可以完成
8)info列,显示这个SQL语句,是判断问题语句的一个重要依据
1.3、explain分析执行计划:
1)id列,select查询的序列号,是一组数字,表示的是查询中执行select子句或者是操作表的顺序
2)select_type列,表示select的类型,常见的取值有SIMPLE(简单表,即不使用表连接或子查询)、PRIMARY(主查询,即外层的查询词)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(子查询中的第一个SELECT)等
3)table列,输出结果集的表
4)type列,表示表的连接类型,性能由好到差的连接类型为(system—>const—>eq_ref—>ref—>ref_or_null—>index_merge—>index_subquery—>range—>index—>all)
5)possible_keys列,表示查询时,可能使用的索引
6)key列,表示实际使用的索引
7)key_len列,索引字段的长度
8)rows列,扫描行的数量
9)extra列,执行情况的说明和描述
#ref:显示该表的索引字段关联了哪张表的哪个字段的类型
#filtered:返回结果的行数占读取行数的百分比,值越大越好
explain之id:
id字段是select查询的序列号,是一组数字,表示的是查询中select子句或者是操作表的顺序,id情况有三种:
- id相同表示加载表的顺序是从上到下。
- id不同id值越大,优先级越高,越先被执行。
- id有相同,也有不同,同时存在。id相同的可以认为是一组,从上往下顺序执行;在所有的组中,id的值越大,优先级越高,越先执行。
explain之select_type:
表示select的类型,常见的取值,如下所示,效率从上到下越来越低:
SIMPLE:简单的select查询,查询中不包含子查询或者UNION
PRIMARY:查询中若包含任何复杂的子查询,最外层查询标记为该标识
SUBQUERY:在SELECT或WHERE列表中包含了子查询
DERIVED:在FROM列表中包含的子查询,被标记DERIVED(衍生)MYSQL会递归执行这些子查询,把结果放在临时表中
UNION:若第二个SELECT出现在UNION之后,则标记为UNION;若UNION包含在FROM子句的子查询,外层SELECT将被标记为DERIVED
UNION RESULT:从UNION表获取结果的SELECT
explain之table:
展示这一行的数据是关于哪一张表的
explain之type:
type显示的是访问类型,是较为重要的一个指标,可取值为:
NULL:MYSQL不访问任何表,索引,直接返回结果
system:表只有一条记录(等于系统表),这是const类型的特例,一般不会出现
const:表示通过索引一次就找到了,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快。如将主键置于where列表中,MYSQL就能将查询转换为一个常量。const于将“主键”或“唯一”索引的所有部分与常量值进行比较
eq_ref:类似ref,区别在于使用的是唯一索引,使用主键的关联查询,关联查询出的记录只有一条。常见于主键或唯一索引扫描
ref:非唯一索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,返回所有匹配某个单独值的所有行(多个)
range:只检索给定返回的行,使用一个索引来选择行。where之后出现between,<,>,in等操作。
index:index与ALL的区别为index类型只是遍历了索引树,通过比ALL快,ALL是遍历数据文件
ALL:将遍历全表以找到匹配的行
explain之key
possible_keys:显示可能应用在这张表的索引,一个或者多个
key:实际使用的索引,如果为NULL,则没有使用索引
key_len:表示索引中使用字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越发。
explain之rows:
扫描行的数量
explain之extra:
其它的额外的执行计划信息,在该列展示:
using filesort:说明MYSQL会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取,称为“文件排序”,效率低。
using temporary:使用了临时表保存中间结果,MYSQL在对查询结果排序时使用临时表。常见于order by 和group by;效率低
using index:表示相应的select操作使用了覆盖索引,避免访问表的数据行,效率不错。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/276294.html