SQL性能分析大家好。我是电脑程序编制员。这段时间一直在分享MySQL索引系列的文章。我们学习了B+树索引模型和索引长度的计算。很明显,使用Delete删除了数据。但是为什么磁盘上的数据文件大小没有变化呢?等等,今天开始学习SQL优化。说到SQL优化,我们需要知道一条SQL的执行频率。如果你有一个几个月才执行一次的慢SQL,那我觉得你不需要花精力去优化它。毕竟执行频率太低了。投入产出比不够。SQLexecutionfrequency关于查询SQL的执行频率,我们可以使用showglobalstatuslike'Com___',(这后面有7个下划线),这个命令可以显示当前数据库中每条语句的使用次数,比如增加,删除,修改查看,可以看到我的,在我的库中,大量的执行语句都是select语句,其他语句很少。就是说这个库的查询很多,所以我们需要格外注意查询的效率。关于具体的查询效率,我们可以通过查询数据库的慢SQL日志来查询。慢查询日志是否开启慢查询日志:showvariableslike'slow_query_log'开启慢日志:setglobalslow_query_log=1;(只对当前session有效,全局生效需要修改my.conf配置文件)设置慢查询阈值:设置globallong_query_time=4,可以在slow.log文件中查询执行过的慢SQL。这部分足以基本掌握这些命令。我们可以在临时会话中启用慢SQL日志,然后执行相应的SQL语句来记录日志。慢查询日志可以帮助我们记录具体的慢查询语句,但是并没有告诉我们为什么慢。因此,我们需要借助一些其他的命令来帮助我们找出查询慢的具体原因。使用MySQL的profiling功能分析单个queryshowprofiles可以帮助我们了解在做SQL优化的时候,时间花在了哪些地方。showprofileforqueryid查看每个阶段的具体耗时。这两个命令的组合可以很清楚的告诉我们SQL在执行到哪一步,比如某个子查询或者server层的数据传输。原因。发现时间消耗在那个环节之后,我们就可以使用具体的执行计划进行有针对性的优化。下面将重点介绍SQL执行计划的使用。explain执行计划结果输出显示:id语句的唯一标识。如果explain的结果中包含多个id值,数量大的先执行;对于id相同的行,表示从上到下依次执行。select_type查询类型有以下取值:table表示当前行访问的是哪个表,如果SQL中定义了别名,则显示表的别名分区和当前查询中匹配记录的分区。对于非分区表,返回nulltype连接类型,有以下值,性能排序如下:system:表只有一行(相当于系统表),system是const的特例typeconst:对于主键或唯一索引的等效查询扫描,最多只返回一行数据。const查询非常快,因为它只需要读取一次。eq_ref:当索引的所有组成部分都被使用时,索引为PRIMARYKEY或UNIQUENOTNULL时使用该类型,性能仅次于system和const。ref:只有满足索引的最左前缀规则,或者索引不是主键或唯一索引时才会发生。如果使用的索引只匹配少量行,性能也不错。fulltext:全文索引ref_or_null:这种类型类似于ref,但MySQL会额外搜索哪些行包含NULL。该类型常见于解析子查询index_merge:该类型表示使用索引合并优化,表示在一个查询中使用多个索引unique_subquery:该类型类似于eq_ref,但是使用IN查询,子查询是主键或唯一索引。index_subquery:与unique_subquery类似,只是子查询使用的是非唯一索引范围:rangescan,表示已经检索到指定范围的行,主要用于有限索引扫描。比较常见的范围扫描是BETWEEN子句或WHERE子句,带有>、>=、<、<=、ISNULL、<=>、BETWEEN、LIKE、IN()等操作符。index:全索引扫描,类似于ALL,只不过index是对索引数据进行整体扫描。当查询仅使用索引中列的子集时使用此类型。触发的场景有两种:如果索引是查询的覆盖索引,并且索引查询到的数据可以满足查询中需要的所有数据,则只扫描索引树。此时explain的Extra列结果为Usingindex。index通常比ALL快,因为索引的大小通常小于表数据。为了按照索引的顺序查找数据行,执行全表扫描。此时explain的Extra栏中不会出现Uses索引。ALL:全表扫描,性能最差。possible_keys显示当前查询可以使用哪些索引。该列中的数据是在优化过程的早期创建的,因此某些索引可能对后续优化过程没有用处。key表示MySQL实际选择的索引key_len索引使用的字节数。由于存储格式的原因,字段允许NULL时,key_len比不允许NULL时大1个字节。ref表示将哪个字段或常量与键列使用的字段进行比较。如果ref是函数,则使用的值是函数的结果。要查看它是哪个函数,请在EXPLAIN语句后跟一个SHOWWARNING语句。rowsMySQL估计要扫描的行数,值越小越好。filtered表示满足查询条件的数据百分比,最大为100。使用rows×filtered得到连接到下一张表的行数。比如rows=1000,filtered=50%,那么下一张表连接的行数就是500。以上是explain执行计划结果中字段的说明。很多具体的意思我都是直接从官网拿来的,比较无聊。当然,你不需要死记硬背。只要在SQL优化过程中有意识地使用explain分析其执行计划,然后查找各个字段的含义,最后针对具体问题进行优化,就可以了。关于explain的具体使用,我会在下一篇文章中进行实战练习。今天就简单介绍一下这几个字段的含义,大家可以有个大概的印象。
