当数据量非常庞大时,使用MySQL进行select操作可能会出现耗时特别多的情况。例如:在一张百万数据的表格good中执行select * from good;查询耗时可能需要十几秒,让客户等待十几秒,是不被接受的, 此时我们就需要对相关语句进行性能分析并优化。下面就一起看一下MySQL的性能分析工具和优化策略。
MySQL客户端连接成功后,通过 show [session|global] status命令可以提供服务器状态信息。通过如下指令,可以查看当前数据库的insert 、update、 delete、 select的访问频次。通过查看各种操作的执行频次就可判断是否需要进行性能优化。
show global status like 'Com______'
慢查询日志记录了所有执行时间超出阈值(指定参数 long_query_time ,单位:秒,默认10秒)的所有SQL语句的日志。MySQL慢查询日志默认没有开启,需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息:
#开启慢查询日志
slow_query_log=1
#修改慢查询时间(单位秒)
long_query_time=2
配置完毕之后,通过以下指令重新启动MySQL服务器进行测试,查看慢日志文件中记录的信息(/var/lib/mysql/localhost-slow.log).
上图就是我执行select avg(salary) from salaries; 查询语句花费3.763931秒,超过了阈值2秒,所以记录在慢查询日志中。
show profiles 能够在做SQL优化时帮助我们了解事件都耗费到哪里去了。通过 have_profiling 参数,能够看到当前MySQL是否支持profile操作。
select @@have_profiling;
【结果说明】:yes 表示支持profiling;no 表示不支持
默认profiling是关闭的,可以通过set语句在session|global级别开启profiling:
set profiling=1; //开启profiling
【结果说明】: 1 表示profiling已经开启;0 表示未开启,需要set profiling=1;手动开启。
在执行一系列SQL业务操作后,可以通过如下指令查看指令的执行耗时情况:
#查看每一条SQL的耗时基本情况
show profiles;
上图是当前会话中我执行的每一条SQL的耗时基本情况。
#查看指定query_id的SQL语句各个阶段的耗时情况
show profile for query query_id;
#查看指定query_id的SQL语句cpu使用情况
show profile cpu for query query_id;
上图是一个示例,它们执行的行数可能不一样,但是我们可以从结果中发现这条SQL语句主要耗时在哪个阶段。
【小结】profile可以看到每条SQL语句的耗时及主要耗时在哪个阶段。
使用 EXPLAIN 或 DESC命令获取MySQL如何执行select语句的信息,包括在select语句执行过程中表如何连接和连接的顺序。
#使用语法:直接在select语句前加上关键字explain或desc
explain select语句;
explain 执行计划详细参数:
参数 | 参数说明 |
id | select查询序列号,表示查询中执行select子句或者操作表的顺序(id相同,执行顺序从上到下;id 不同,值越大越先执行)。 |
select_type | select类型,常见取值有SIMPLE(简单表,表示不使用表连接或子查询)、PRIMARY(主查询,外层的查询)、UNION(UNION中的第二个或后面的查询语句)、SUBQUARY(select/where之后包含子查询) |
type | 连接类型,性能由好到差的连接类型为NULL、system、const、eq_ref、ref、range、index、all |
possible_key | 显示可能应用的索引(一个或多个) |
key | 实际使用的索引,如果为NULL,则没有用索引。 |
ken_len | 表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好 |
rows | 预计需要扫描的记 |