慢SQL问题全解析:原因诊断与性能优化策略

发布于:2024-05-06 ⋅ 阅读:(27) ⋅ 点赞:(0)

慢SQL的定义:

        执行时间长的

慢SQL的筛选:

1.使用MySQL自带的日志

查看慢查询日志是否开启:

SHOW VARIABLES LIKE '%slow_query_log%';

开启慢查询日志:使用该方法开启MySQL的慢查询日志只对当前数据库生效,如果MySQL重启后会失效。

SET GLOBAL slow_query_log = 1;
2.Druid数据库连接池

Druid连接池MySQL配置1

Druid连接池MySQL配置2

3.自己实现:

借助AOP记录时间:自己使用AOP记录每一个SQL执行的时间

引起慢SQL的原因:

资源不足:
  •  线程太多
    • 查看CPU负载:top指令
    • 查看进程的负载:
  • 内存不足
    • 查看内存占用:top
    • 查看硬盘的使用情况:df -h
  • 数据量太大
    • 插入数据库数据量太大:分批插入:从500条开始,逐步增长批量条数
    • 查询的数据量比较大:
      • 分库分表
      • 限定查询条件
      • 读写分离:适合查询次数非常高,更新频次非常高
  • 网络不好
    • 判断网络使用情况:netstat
错误使用
  • SQL使用不当
  • 数据量太大
  • 网络不好
  • 表设计不当
  • 查询条件太多
  • 解决慢SQL
  • 索引失效
    • 联合索引不满足最左匹配原则

      联合索引遵从最左匹配原则,顾名思义,在联合索引中,最左侧的字段优先匹配。因此,在创建联合索引时,where子句中使用最频繁的字段放在组合索引的最左侧。

      而在查询时,要想让查询条件走索引,则需满足:最左边的字段要出现在查询条件中。

    • 使用了select *

    • 索引列参与运算

    • 索引列参使用了函数

    • 错误的Like使用

      • 占位符出现在首部
    • 参数类型与字段类型不匹配,导致类型发生了隐式转换,索引失效。

      • id_no字段类型为varchar,但在SQL语句中使用了int类型,导致全表扫描。

        出现索引失效的原因是:varchar和int是两个种不同的类型。

    • 查询条件使用or关键字,其中一个字段没有创建索引,则会导致整个查询语句索引失效; or两边为“>”和“<”范围查询时,索引失效。

    • 如果两个列数据都有索引,但在查询条件中对两列数据进行了对比操作,则会导致索引失效。

    • 查询条件使用不等进行比较时,需要慎重,普通索引会查询结果集占比较大时索引会失效

    • 查询条件使用is null时正常走索引,使用is not null时,不走索引

    • 查询条件使用not in时,如果是主键则走索引,如果是普通索引,则索引失效

    • 查询条件使用not exists时,索引失效

    • 当查询条件涉及到order by、limit等条件时,是否走索引情况比较复杂,而且与Mysql版本有关,通常普通索引,如果未使用limit,则不会走索引。order by多个索引字段时,可能不会走索引。其他情况,建议在使用时进行expain验证。

    • 当查询条件为大于等于、in等范围查询时,根据查询结果占全表数据比例的不同,优化器有可能会放弃索引,进行全表扫描。

    • Mysql优化器的其他优化策略,比如优化器认为在某些情况下,全表扫描比走索引快,则它就会放弃索引。

EXPLAIN +SQL语句 可以对SQL语句模拟优化器执行SQL查询语句

key

keylen

ref

参考文章:15个必知的Mysql索引失效场景,别再踩坑了-腾讯云开发者社区-腾讯云 (tencent.com)