当前位置: 首页 > news >正文

慢sql问题解决,sql优化,数据库(mysql)

文章目录

  • 1、count效率比较
  • 2、作者遇到的慢sql问题
    • 2.1、使用排序导致变慢问题
    • 2.2、使用LEFT JOIN 导致索引失效的问题
    • 2.3、子查询导致索引失效
  • 3、explain命令介绍
  • 4、阿里云rds数据库(mysql的一种)主键索引查询很慢问题
  • 参考文档

1、count效率比较

  • 所以结论是:按照效率排序的话,count(字段)<count(主键 id)<count(1)=count(*)
  • 所以我建议你,尽量使用 count(*)或count(1)。

2、作者遇到的慢sql问题

2.1、使用排序导致变慢问题

  • 表的数据大概为100万条
  • 问题原因:使用create_time字段排序,但是create_time字段没有增加索引导致速度变慢
  • 原执行速度 2.6秒
    #导致原因
    order by create_time
    
  • 解决方式给字段create_time 增加一个索引,执行速度从2秒变成0.031
    alter table 'system_log' 
    add index 'idx_create_time'
    

2.2、使用LEFT JOIN 导致索引失效的问题

  • 小表sys_user(用户表)
  • 大表system_log (系统日志表),默认system_log.create_time 已经创建了普通索引
  • 问题原因:索引在大表上,使用left join导致大表的索引失效
  • 原执行速度2.6秒
    #导致原因
    from sys_user
    left join system_log on sys_user.id=system_log.user_id
    order by system_log.create_time
    
  • 解决办法一:使用 inner join,执行速度0.031秒
    from sys_user
    inner join system_log on sys_user.id=system_log.user_id
    order by system_log.create_time
    
  • 解决办法二:使用大表驱动小表,执行速度0.033秒
    from system_log 
    left join sys_user on sys_user.id=system_log.user_id
    order by system_log.create_time
    

2.3、子查询导致索引失效

  • rds数据库(mysql的一种),recode_table表记录数5亿,org_table表记录数4万
  • 原执行速度超时(60秒以上)
    SELECT cu.org_no as orgNo,org.org_short_name as orgName,round(sum(qty) /10000, 2)  as aValue,cast(round((sum(qty) -sum(qty_corrprd)) / sum(qty_corrprd) *100, 2)  as decimal(22, 2)) as cValueFROM `org_table` orgleft join recode_table cu on cu.org_no= org.org_noand cu.time_period= '01'and cu.ind_cls in ('0101', '0202', '0303')and cu.stat_date between '20240801'and '20240810'where org.prnt_org_no= '11101'group by org.org_no,org.org_name,org.org_short_name
    
    #等价于
    SELECT cu.org_no as orgNo,org.org_short_name as orgName,round(sum(qty) /10000, 2)  as aValue,cast(round((sum(qty) -sum(qty_corrprd)) / sum(qty_corrprd) *100, 2)  as decimal(22, 2)) as cValue
    from org_table org
    left join(
    select cu.org_no, qty, qty_corrprdfrom recode_table cuwhere cu.time_period= '01'and cu.ind_cls in('0101', '0202', '0303')and cu.stat_date between '20240801'and '20240810'
    ) cu on cu.org_no= org.org_no
    where org.prnt_org_no= '11101'
    group by org.org_no,org.org_name,org.org_short_name
    
  • 解决方式一:把条件都放到where中,执行速度2.5s
    #搜索的结果会有略微差异,org_table关联不上的结果会消失
    SELECT cu.org_no as orgNo,org.org_short_name as orgName,round(sum(qty)  /10000, 2) as aValue,cast(round((sum(qty)  -sum(qty_corrprd))  / sum(qty_corrprd)  *100, 2) as decimal(22, 2))  as cValueFROM `org_table` orgjoin recode_table cu on cu.org_no= org.org_nowhere cu.time_period= '01'and cu.ind_cls in('0101', '0202', '0303')and cu.stat_date between '20240801'and '20240810'and org.prnt_org_no= '11101'group by org.org_no,org.org_name,org.org_short_name
    
  • 解决方式二:把条件都放到where中,同时外层再重复关联org_table表执行速度2.5s
    #多嵌套了一层非常难看,但是可以解决org_table关联结果不丢失的问题
    select org.org_no as orgNo,org.org_short_name as orgName,a.aValue as aValue,a.cValue as cValueFROM org_table org
    left join 
    (
    SELECT cu.org_no as orgNo,org.org_short_name as orgName,round(sum(qty) /10000, 2)  as aValue,cast(round((sum(qty) -sum(qty_corrprd)) / sum(qty_corrprd) *100, 2)  as decimal(22, 2)) as cValueFROM `org_table` orginner join recode_table cu on cu.org_no= org.org_nowhere cu.time_period= '01'and cu.ind_cls in ('0101', '0202', '0303')and cu.stat_date between '20240801'and '20240810'and org.prnt_org_no= '11101'group by org.org_no,org.org_name,org.org_short_name
    ) as a on a.orgNo= org.org_nowhere org.prnt_org_no= '11101'	 
    
  • 解决方法三:使用union 强制让子查询走索引,执行速度0.2s
    SELECT cu.org_no as orgNo,org.org_short_name as orgName,round(sum(qty) /10000, 2)  as aValue,cast(round((sum(qty) -sum(qty_corrprd)) / sum(qty_corrprd) *100, 2)  as decimal(22, 2)) as cValue
    from org_table org
    left join(
    select cu.org_no, qty, qty_corrprdfrom recode_table cuwhere cu.time_period= '01'and cu.ind_cls in('0101', '0202', '0303')and cu.stat_date between '20240801'and '20240810'
    union
    select null,null,null
    ) cu on cu.org_no= org.org_no
    where org.prnt_org_no= '11101'
    group by org.org_no,org.org_name,org.org_short_name
    

3、explain命令介绍

  • explain使用方法及结果分析
  • explain命令可以查看执行计划,在你需要执行的sql语句前面加explain即可
  • filtered越小代表索引的优化效果越好,定位到需要的记录速度越快
  • 例如
    explain select * from `order` where code='002';
    
  • 执行计划包含列的含义
    在这里插入图片描述

4、阿里云rds数据库(mysql的一种)主键索引查询很慢问题

  • where的查询条件也在索引上,但是单表查询的速度非常慢
  • 解决方式:添加多个单字段索引,原本主键字段为date、org_code、type,建3个索引,每个索引对应一个字段
  • 原速度10s,加完之后0.05s
  • 为什么添加单字段索引会变快,这个问题作者也没想通

参考文档

  • sql优化的15个小技巧(必知五颗星),面试说出七八个就有了

http://www.mrgr.cn/news/12698.html

相关文章:

  • 8.26 T4 日记和编辑器(fhq维护kmp——kmp本身含有的单射与可合并性)
  • 浅谈安科瑞系能源配套产品在美特新材料光储充一体化项目上的应用
  • 探索联邦学习:保护隐私的机器学习新范式
  • C# .Net 条码批量自动打印框架 基于Bartender 10.1 V1.0
  • 代码随想录训练营 Day41打卡 动态规划 part08 121. 买卖股票的最佳时机 122. 买卖股票的最佳时机II 123. 买卖股票的最佳时机III
  • Android settings命令讲解和实战
  • [记录] linux 虚拟机装 windows10
  • 免费分享:中国三级及以上河流(附下载方法)
  • HTML静态网页成品作业(HTML+CSS)——世博园介绍(2个页面)
  • vm 虚拟机无法调用摄像头(亲测有效)
  • 边缘物联网平台AIoTedge推荐
  • matlab 创建复数数组
  • 搜维尔科技:利用 Xsens最大程度提高影视动画制作效率
  • 重构多重children数据 减少数据
  • 一道关于php文件包含的CTF题
  • 浅析车辆类型检测算法实际应用车辆类型检测算法源码
  • 【Python机器学习】NLP词中的数学——齐普夫定律
  • 设计模式(一):七大原则
  • 基于x86 平台opencv的图像采集和seetaface6的眼睛状态检测(睁眼,闭眼)功能
  • 用ESP32做一个可爱的无用机器人