MySQL优化 -- SQL及索引优化(一)

一、如何发现有问题的SQL?

使用MySQL慢查询日志对有效率问题的SQL进行监控:

查看是否有开启慢查询日志记录:
show variables like 'slow_query_log';
设置没用到索引的查询都记录:
set global log_queries_not_using_indexes=on;
开启慢查询日志记录:
set global slow_query_log=on;
查看日志相关设置,例如日志存放位置:
show VARIABLES like '%log%';

慢查询日志包含的内容:

select * from city;
# Time: 2020-04-05T07:08:10.574255Z
执行SQL的主机信息:
# User@Host: root[root] @ localhost [::1]  Id:   137
SQL的执行信息:
# Query_time: 0.001917  Lock_time: 0.000480 Rows_sent: 15  Rows_examined: 307
SQL的执行时间:
SET timestamp=1586070490;

二、慢查询日志的分析工具

1、mysqldumpslow工具:
MySQL自带的分析工具,优点是简单使用,将日志信息一条一条分拣出来。缺点是输出的信息内容较少。

查询前三条(滚动查看):
mysqldumpslow -t 3 日志路径 | more

2、pt-query-digest工具:
好处就是能分析总的sql情况,还可以看出每个查询的次数,时间等信息。

输出到文件:
pt-query-digest slow-log > slow_log.report
输出到数据库表:
pt-query-digest slow.log -review \ h=127.0.0.1,D=test,p=root,P=3306,u=root,t=query_review \
--create-reviewtable \ --review-history t= hostname_slow

结果分析,第一部分:显示日志的时间范围,总的sql数量和不同的sql数量。
在这里插入图片描述
第二部分:响应时间占比,sql执行次数。
在这里插入图片描述
第三部分:具体每条查询sql分析。
在这里插入图片描述

三、如何通过慢查询日志发现有问题的SQL?

1、查询次数多且每次查询占用时间长的SQL
通常为pt-query-digest分析的前几个查询。
2、IO大的SQL
注意pt-query-digest分析中的Rows examine选项。
3、未命中索引的SQL
注意pt-query-digest分析中Rows examine 和 Rows Send的对比。

四、如何分析SQL查询?

使用explain查询SQL的执行计划。
在这里插入图片描述
explain返回各列的含义:

table:显示关于哪张表。
type:这是重要的列,显示连接使用了何种类型。从最好到最差,分别是const,eq_reg,ref,range,index,all。
possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。
key:实际使用的索引,如果为null,则没有使用索引。
key_len:使用的索引的长度,在不损失精确性的情况下,长度越短越好。
ref:显示索引的哪一列被使用,如果可能的话,是一个常数。
rows:MySQL认为必须检测的用来返回请求数据的行数。
extra列需要注意的返回值:
Using filesort:看到这个,查询就需要优化了。MySQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行。
Using temporary:看到这个,查询就需要优化了。MySQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行order by上,而不是group by上。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL索引是数据库中的一个重要概念,它能够提高查询效率索引优化可以大大提高查询性能,减少数据库的负载。在MySQL中,我们可以通过EXPLAIN命令来查看SQL查询是否命中索引。 举例说明: 假设有一个学生表,字段包括id、name、age、sex、class等。我们需要查询年龄为18岁的学生信息,SQL语句如下: SELECT * FROM student WHERE age = 18; 为了优化查询效率,我们可以为age字段添加索引SQL语句如下: ALTER TABLE student ADD INDEX age_idx(age); 再次执行查询语句时,我们可以通过EXPLAIN命令来查看是否命中索引SQL语句如下: EXPLAIN SELECT * FROM student WHERE age = 18; 执行结果如下: +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | student | NULL | ref | age_idx | age_idx | 5 | NULL | 10 | 100.00 | Using where | +----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+ 可以看到,type列显示为ref,表示使用了索引。如果没有命中索引,type列可能显示为ALL或Using filesort等,查询效率会非常。 在实际开发中,我们可以根据需要为表的关键字段添加索引,但过多的索引也会影响数据库的性能。因此,需要根据实际情况进行合理的索引优化

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值