在做MySQL数据的性能定位前,需要先知道MySQL查询时数据库内部的执行过程。只有弄清SQL的执行过程,才能对执行过程中的每一步的性能做定位分析。如图6-2-1所示。
图6-2-1
从图中可以看到,当查询出数据以后,会将数据先返回给执行器,此时执行器先将结果写到查询缓存里面,这样在下次查询相同的数据时,就可以直接从缓存中查询并且返回,同时将结果返回给客户端。分析器会对待查询的SQL语句做执行计划的分析,而优化器会对SQL语句做重新优化,以便SQL的查询性能达到最佳。
6.2.1 慢SQL
每条SQL语句在执行时都需要消耗一定的I/O资源,SQL语句执行的快慢直接决定了硬件资源被占用时长的长短,慢SQL一般指查询很慢的SQL语句。在MySQL数据库中,可以通过慢查询来查看所有执行超时的SQL语句。在默认情况下,一般慢SQL是关闭的,可以通过执行show variables like 'slow_query%' 来查看数据库是否开启了慢查询,如图6-2-2所示。
从图6-2-2中看到slow_query_log的值为OFF表示慢查询未开启,可以通过执行命令“set global slow_query_log=1; ”或者“set global slow_query_log=ON;”来临时开启慢查询,如图6-2-3所示。
如果需要永久开启,就需要修改/etc/my.cnf配置文件,在[mysqld]处加入如下配置,再重启数据库即可生效,如下所示。
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/localhost-slow.log
修改完成重启数据库后,再次执行show variables like 'slow_query%',发现慢查询已经被开启,如图6-2-4所示。
通过执行“show variables like 'long_query%';”可以查询慢查询的记录时间,如图6-2-5所示。慢查询的记录时间默认是10秒,可以通过执行“set long_query_time=需要修改的时长;”来修改慢查询的记录时间。
通过执行“show status like 'slow_queries';”可以查看慢查询发生的次数,如图6-2-6所示。
从慢查询日志中,我们也可以看到慢查询发生的详细信息,如图6-2-7所示。慢查询日志中会记录每次慢查询发生的时间、执行查询时的数据库用户、线程id、查询执行的SQL语句等信息。
在获取到慢查询的SQL语句后,就可以借助数据库的执行计划来对慢查询的SQL语句做进一步的分析。(节选自《软件性能测试、分析与调优实践之路》(第2版),作者张永清,转载请注明出处)
6.2.2 执行计划
在MySQL中使用explain关键字可以模拟查看数据库是如何执行SQL查询语句,也就是常说的查看一条SQL语句在数据库中的执行计划。图6-2-8所示就是执行EXPLAIN SELECT * FROM test.test 后返回的SELECT * FROM test.test查询的执行计划。
查询结果返回的字段说明如下所示。
(1)id。查询的顺序编号,表示查询中执行的顺序。id的值越大,执行的优先级越高;如果id相同,则从上往下执行。
(2)select_type。查询类型,常见查询类型说明如下:
(3)table。查询涉及的表名或者表的别名。
(4)type。表示表连接的类型,包括的类型说明如下。这些类型的性能从高到低的顺序是null→system→const→eq_ref→ref→fulltext→ref_or_null→index_merge→unique_subquery→index_subquery→range→index→ALL。
(5)possible_keys。查询时预计可能会使用的索引。这里说的索引只是可能会用到,实际查询不一定会用到。
(6)key。实际查询时真实使用的索引。
(7)key_len。使用的索引长度。
(8)ref 。关联信息。
(9)rows。查询时扫描的数据记录行数。
(10)extra。表示查询特性的使用情况。常用的查询特性如下所示:
6.2.3 MySQL数据库性能定位步骤
MySQL数据库性能定位的常见步骤总结如图6-2-8所示。
图6-2-8
(1)首先通过本书第2章中服务器的性能监控与分析,找到当前服务器的资源使用情况,重点关注CPU、内存、磁盘等使用率。
(2)根据服务器资源的使用率情况,初步判断当前MySQL数据库可能在执行的操作类型。(节选自《软件性能测试、分析与调优实践之路》(第2版),作者张永清,转载请注明出处)
(3)通过在数据库中执行SHOW FULL PROCESSLIST 命令观察当前正在运行的SQL 命令,可以每间隔5~10s 多执行几次该命令,找到哪些SQL操作是持续一直在运行中。
(节选自《软件性能测试、分析与调优实践之路》(第2版),作者张永清,转载请注明出处)