mysql的慢sql优化

为什么要优化慢sql ?

慢sql会长时间占用 数据库连接数,如果项目中有大量的慢sql,那么可用的数据库连接数就会变少,进而会影响业务。

慢sql优化

  • 优化慢sql,最常见的就是添加索引。

  • 查询语句中不要使用select *

  • 尽量减少子查询,使用关联查询(left join,right join,inner join)替代

  • 减少使用IN或者NOT IN ,使用exists,not exists或者关联查询语句替代

  • or 的查询尽量用 union或者union all 代替(在确认没有重复数据或者不用剔除重复数据时,union all会更好)

  • 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

  • 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
    select id from t where num is null
    可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
    select id from t where num=0

  • 对于like查询,"%"不要放在前面。

      SELECT * FROM  t_order  WHERE uname LIKE '编程%' -- 走索引 
      SELECT * FROM  t_order  WHERE uname LIKE  '%编程%' -- 不走索引
    

可以用instr代替左模糊。

instr(title,'name')>0  相当于  title like '%name%' 
instr(title,'name')=1  相当于  title like 'name%' 
instr(title,'name')=0  相当于  title not like '%name%' 

EXPLAIN查看执行计划

EXPLAIN可以查看执行计划,对 SELECT 语句进行分析,并输出 SELECT 执行的详细信息,方便针对性地优化。

查询结果的字段如下:

    select_type: SELECT 查询的类型。包括SIMPLE、PRIMARY、UNION、UNION RESULT等
    table: 查询的是哪个表
    partitions: 匹配的分区
    type(重要): 类型。type值为all,表示全表扫描。type值为const,说明使用了主键索引。

system: 表中只有一条数据. 这个类型是特殊的 const 类型.

const: 针对主键或唯一索引的等值查询扫描, 最多只返回一行数据. const 查询速度非常快, 因为它仅仅读取一次即可.

eq_ref: 此类型通常出现在多表的 join 查询, 表示对于前表的每一个结果, 都只能匹配到后表的一行结果. 并且查询的比较操作通常是 =, 查询效率较高.

ref: 此类型通常出现在多表的 join 查询, 针对于非唯一或非主键索引, 或者是使用了 最左前缀 规则索引的查询.

range: 表示使用索引范围查询, 通过索引字段范围获取表中部分数据记录. 这个类型通常出现在 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN() 操作中.

当 type 是 range 时, 那么 EXPLAIN 输出的 ref 字段为 NULL, 并且 key_len 字段是此次查询中使用到的索引的最长的那个.

index: 表示全索引扫描(full index scan), 和 ALL 类型类似, 只不过 ALL 类型是全表扫描, 而 index 类型则仅仅扫描所有的索引, 而不扫描数据.

index 类型通常出现在: 所要查询的数据直接在索引树中就可以获取到, 而不需要扫描数据. 当是这种情况时, extra 字段 会显示 Using index.

all: 表示全表扫描, 这个类型的查询是性能最差的查询之一. 通常来说, 我们的查询不应该出现 ALL 类型的查询, 因为这样的查询在数据量大的情况下, 对数据库的性能是巨大的灾难. 如一个查询是 ALL 类型查询, 那么一般来说可以对相应的字段添加索引来避免.

不同的 type 类型的性能关系如下:

ALL < index < range ~ index_merge < ref < eq_ref < const < system。

    possible_keys: 此次查询中可能选用的索引
    key(重要): 此次查询中确切使用到的索引.
    ref: 哪个字段或常数与 key 一起被使用
    rows(重要): 显示此查询一共扫描了多少行. 这个是一个估计值.
    filtered: 表示此查询条件所过滤的数据的百分比
    extra: 额外信息,比如using index表示使用覆盖索引,using where表示在存储引擎之后进行过滤,using temporary表示使用临时表,using filesort表示对结果进行外部排序。

技术角度

  • 用EXPLAIN 查看执行计划。
  • 拆解sql,复杂的sql拆成多条sql,再用 java代码拼接。
  • 复杂的sql,在上线之前,先去生产环境 EXPLAIN 一下执行计划。

业务角度

  • 与产品/业务讨论,查询时,能否限制时间范围,比如只查七天、只查一个月。
  • 与产品/业务讨论,能否清理无用的旧数据,只保留最近三个月、最近一年的数据。
相关推荐
Jacky(易小天)2 分钟前
MongoDB比较查询操作符中英对照表及实例详解
数据库·mongodb·typescript·比较操作符
Karoku06641 分钟前
【企业级分布式系统】ELK优化
运维·服务器·数据库·elk·elasticsearch
莫叫石榴姐1 小时前
数据科学与SQL:组距分组分析 | 区间分布问题
大数据·人工智能·sql·深度学习·算法·机器学习·数据挖掘
小技与小术2 小时前
数据库表设计范式
数据库·mysql
安迁岚2 小时前
【SQL Server】华中农业大学空间数据库实验报告 实验三 数据操作
运维·服务器·数据库·sql·mysql
安迁岚2 小时前
【SQL Server】华中农业大学空间数据库实验报告 实验九 触发器
数据库·sql·mysql·oracle·实验报告
Loganer2 小时前
MongoDB分片集群搭建
数据库·mongodb
LKID体2 小时前
Python操作neo4j库py2neo使用之创建和查询(二)
数据库·python·neo4j
刘大浪2 小时前
后端数据增删改查基于Springboot+mybatis mysql 时间根据当时时间自动填充,数据库连接查询不一致,mysql数据库连接不好用
数据库·spring boot·mybatis
一只爱撸猫的程序猿2 小时前
简单实现一个系统升级过程中的数据平滑迁移的场景实例
数据库·spring boot·程序员