Mysql 优化之查询截取分析

查询优化

1. 小表驱动大表

MySQL 只支持循环嵌套算法,因此驱动结果集越大,所需要的循环就越多,那么被驱动表的访问次数也就越多,而每次访问表,都会产生 IO 访存,因此循环次数越多,IO 访存也越多,并且每次循环都要消耗 CPU。因此我们应该尽量选择更小的驱动表,也即小表驱动大表。

现有表A(员工表),B(部门表),id 为部门 id。

因此 A 中有很多列,为大表,B 中的列较少,为小表。

表 A 与表 B 的 id 字段建立了索引。

#-------1.in---------- 
select * from A where id in (select id from B)
#等价于
for select id from B    #表B有n列,对表B访存n次
    for select * from A where A.id = B.id    #对表A访存n次,无论A有多少列

#------2.exists-------
select * from A where exists (select * from B where B.id = A.id)
#等价于
for select * from A    #表A有n列,对表A访存n次
    for select * from B where B.id = A.id    #对表B访存n次,无论B有多少列

驱动表越小,IO 访存越少

需要注意的是,我们不能只看表的大小,应该看经 where 过滤之后表的大小,如:

select * from A where name = "bob" and id in (select id from B)

此时驱动表应该为表 A 中姓名为 bob 的列,有可能会比表 B 小。

2. ORDER BY 与 GROUP BY 关键字优化

ORDER BY 尽量使用索引进行排序,以避免产生FileSort;GROUP BY 实际上是先排序后分组,可类比 ORDER BY。


慢查询日志

1. 慢查询日志是什么
  1. MySQL 的慢查询日志是 MySQL 提供的一种日志记录,它用来记录在 MySQL 中响应时间超过阈值的语句,具体指运行时间超过 long_query_time 值的 SQL,则会被记录到慢查询日志中。

  2. 具体指运行时间超过 long_query_time 值的 SQL,则会被记录到慢查询日志中。long_query_time 的默认值为10,意思是运行10秒以上的语句。

  3. 由他来查看哪些 SQL 超出了我们的最大忍耐时间值,比如一条 sql 执行超过5秒钟,我们就算慢 SQL,希望能收集超过5秒的 sql,结合之前 explain 进行全面分析。

2. 如何启动慢查询日志
  1. 默认情况下,MySQL 数据库没有开启慢查询日志,需要我们手动来设置这个参数。

  2. 如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件。

    SQL描述
    show variables like ‘%slow_query_log%’;查看慢查询日志是否开启
    set global slow_query_log=1;开启慢查询日志
    show variables like ‘long_query_time%’;查看慢查询设定阈值(单位:秒)
    set long_query_time=1设定慢查询阈值(单位:秒)
    show global status like ‘%slow_queries%’;查询超过阈值的 SQL 语句数量
3. 查看慢查询日志
  1. SHOW VARIABLES LIKE '%slow_query_log%';可以查看慢查询日志是否开启,以及慢查询日志保存的位置:

1

第二列可以看出日志保存在 /var/lib/mysql/localhost-slow.log 文件中。

  1. 查看慢查询日志

通过 select sleep 制造高耗时的 SQL 语句:

2
通过 cat 指令获取文件内容:

3

上述信息有:

  • 时间: Time: 210523 9:15:06,表示这是21年05月23日9:15:06产生的 SQL

  • 用户: User@Host: root[root],表示执行该 SQL 语句的用户是 root

  • 执行时间: Query_time: 2.009751

  • 使用的数据库: use db1;

  • 时间戳: SET timestamp=1621775706;

  • 超过阈值的 SQL:select sleep(2);


Show Profile

1. Show Profile 的作用
    Show Profile 是一个查询剖析工具,默认是禁止的。开启 Show Profile 后,在服务器上执行的所有 SQL 语句,都会测量其耗费的时间和其他一些查询执行状态变更的相关数据。

    当一条查询提交给服务器时,此工具会记录剖析信息到一张临时表上,并给查询赋予一个从 1 开始的整数标识符。
2. 开启 Show Profile

Show Profile 默认是禁止的,因此需要先开启 Show Profile。

Set profiling=1;开启 Show Profile

Show Variables Like '%profiling%'查看 Show Proflie 状态

4

Variable_nameValue备注
have_profilingYES是否具备 Show Profile 功能
profilingONShow Profile 是否开启
profiling_history_size15Show Profile 缓存大小
3. 如何使用 Show Profile

通过Show Profiles可以查询最近几次的 SQL 执行时间,注意 Profiles 是复数。

5

profiling_history_size = 15,Show Profile 便记录下了最近的15条 SQL 语句,以及他们所消耗的时间。

通过show profile for query N可以查询第 N 条 SQL 具体执行时间:
在这里插入图片描述

通过show profile cpu,block io for query N可以查询第 N 条 SQL 的 CPU 及 IO 占用:
在这里插入图片描述

剖析报告给出了查询执行的每个步骤及其花费时间,可以针对花费时间较多的步骤进行优化。


全局查询日志

1. 全局查询日志是什么
    开启全局查询日志将会记录所有执行的 SQL 语句,会对系统性能产生负担,默认不开启,一般在测试环境下开启。
2. 开启全局查询日志
  1. 修改配置文件 my.cnf 开启

    开启:general_log = 1

    全局查询日志保存路径:general_log_file = /path/logfile

    输出格式:log_output = FILE

  2. 使用编码开启

    set global general_log = 1

    set global log_output = 'TABLE'

    此后,所有执行的 SQL 语句都会记录到 mysql 库中的 general_log 表中;

    通过select * from mysql.general_log语句查看 general_log 表:

8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值