wanjichun 2020-06-10
MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。 当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。
查看是否开启: show variables like ‘%slow_query_log%‘; 开启慢查询日志:set global slow_query_log=1; (重启会失效) 开启了慢查询日志后,什么样的SQL才会记录到查询日志里面? 这个是由参数long_query_time控制,默认情况下long_query_time的值为10秒 查看命令: show variables like ‘long_query_time%‘; 注: 永久设置慢查询日志开启,以及设置慢查询日志时间临界点(不建议) linux中,mysql配置文件一般默认在 /etc/my.cnf 更改对应参数即可
设置阀值命令: set global long_query_time=3 (修改为阀值到3秒钟的就是慢sql) 为什么设置后看不出变化: 需要重新连接或新开一个会话才能看到修改值。 show variables like ‘long_query_time%‘; 直接 show global variables like ‘long_query_time‘; 查看慢查询日志: cat -n /data/mysql/mysql-slow.log 从慢查询日志中,我们可以看到每一条查询时间高于3s 的sql语句,并可以看到执行的时间是多少。
在生产环境中,如果要手工分析日志,查找、分析SQL,显然是个体力活,MySQL提供了日志分析工具 mysqldumpslow s: 是表示按照何种方式排序 c: 访问次数 l: 锁定时间 r: 返回记录 t: 查询时间 al:平均锁定时间 ar:平均返回记录数 at:平均查询时间 t:即为返回前面多少条的数据 g:后边搭配一个正则匹配模式,大小写不敏感的 工作常用参考: 得到返回记录集最多的10个SQL: mysqldumpslow -s r -t 10 /var/lib/mysql/mysql-slow.log 得到访问次数最多的10个SQL: mysqldumpslow -s c -t 10 /var/lib/mysql/mysql-slow.log 得到按照时间排序的前10条里面含有左连接的SQL: mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/mysql-slow.log 建议: 为方便 可以结合 | 和 more 使用,否则可能出现爆屏 mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log | more
详见SQL优化篇
详见索引篇
Explain简称执行计划,使用Explain关键字可以模拟优化器执行SQL查询语句 用法:explain + SQL
select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
查询的类型,主要是用于区分 普通查询、联合查询、子查询等的复杂查询 simple:简单的select 查询,查询中不包含子查询或者 union primary:查询中若包含任何复杂的子部分,最外层查询则被标记为 subquery:在select或where列表中包含了子查询 derived:在from 列表中包含的子查询被标记为 derived(衍生) union:若第二个select出现在之后,则被标记为 union(若union 包含from 子句的子查询中,外层select将被标记为:derived) union result:从union 表获取结果的 select
显示这一行的数据是关于哪张表的
访问类型排列,显示查询使用了何种类型 从好到坏,system > const > eq_ref > ref > range > index > all system:表只有一行记录(等于系统表),这是const 类型的特列,平时不会出现,这个也可以忽略不计 const:表示通过索引一次就找到了,const 用于比较 primary key或者unique索引 eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描 ref:非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问 range:只检索给定范围的行,使用一个索引来选择行。key 列显示使用了哪个索引,一般就是在你的where语句中出现了 between、<、>、in等的查询 index:Full Index Scan,index与 all 区别为 index 类型只遍历索引树 all:Full Table Scan,将遍历全表以找到匹配的行
显示可能应用在这张表的索引,一个或多个。(但不一定被实际应用)
实际使用的索引,如果为null,则没有使用索引。 查询中若使用了覆盖索引,则该索引与查询的select字段重叠
表示索引中使用的字节数
显示索引的哪一列被使用,如果可能的话,是一个常数,哪些列或常量被用于查找索引列上的值
根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数
包含不适合在其他列中显示但十分重要的额外信息 Using filesort (劣): mysql 会对数据使用一个外部的索引排序(文件排序),而不是照表内的索引顺序进行读取 Using temporary (劣):使了用临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by Using index (优):表示相应的select操作中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率不错! Using where:表明使用了where 过滤 Using join buffer:表明使用了连接缓存 impossible where:where子句的值总是false,不能用来获取任何数据 select tables optimized away: select操作已经优化到不能再优化了(MySQL根本没有遍历表或索引就返回数据了 distinct:在select部分使用了distinc关键字
针对explain命令生成的执行计划,这里有一个查看心法。我们可以先从查询类型type列开始查看,如果出现all关键字,后面的内容就都可以不用看了,代表全表扫描。 再看key列,看是否使用了索引,null代表没有使用索引。 然后看rows列,该列用来表示在SQL执行过程中被扫描的行数,该数值越大,意味着需要扫描的行数越多,相应的耗时越长, 最后看Extra列,在这列中要观察是否有Using filesort 或者Using temporary 这样的关键字出现,这些是很影响数据库性能的。