前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[MySQL] SQL优化案例1

[MySQL] SQL优化案例1

原创
作者头像
夜半钟鸣
修改2021-02-25 10:25:41
3220
修改2021-02-25 10:25:41
举报
文章被收录于专栏:小树洞小树洞

原始SQL如下,MySQL版本5.7.19。执行时间1小时以上无法出结果

代码语言:javascript
复制
 SELECT *
 FROM
   ( SELECT a.*,
            e.PAGY_STAT,
            b.brname,
            c.SETL_TYPE,
            c.SETL_SYMBOL,
            c.SETL_CYCLE,
            c.spec_Setl_Day,
            c.SETL_ACCT_NAME,
            c.SETL_ACCT_NO,
            f.MCC_DESC,
            IF (substring(a.mcht_id,1,10)='8201806132',
                                          '1',
                                          '0') AS IS_CUN_LIANG,
               d.audit_dt,
               IF (g.mcht_id IS NOT NULL,
                                '01',
                                '00') AS is_huohu,
                  IF (g.FLAG='2'
                      OR g.FLAG='0',
                                '01',
                                '00') AS is_high_quality
    FROM pbs_mcht_base_info a
    LEFT JOIN ifs_org b ON a.MCHT_ORG_ID = b.brcode
    LEFT JOIN pbs_mcht_contr_info c ON a.mcht_id =c.mcht_id
    LEFT JOIN
      (SELECT MCHT_ID,
              SUBSTR(MAX(LAST_UPD_DATE_TIME),1,8) audit_dt
       FROM pmp_audit_info
       WHERE AUDIT_STATE='01'
       GROUP BY MCHT_ID) d ON d.mcht_id=a.mcht_id
    LEFT JOIN
      (SELECT mcht_id,
              IF(PAGY_MCHT_ID IS NULL
                 OR PAGY_MCHT_ID ='',
                                  '01',
                                  '00') AS PAGY_STAT
       FROM pbs_mcht_base_info) e ON a.mcht_id = e.mcht_id
    LEFT JOIN pbs_mcht_mcc_info f ON a.mcht_Mcc_Code = f.mcc_id
    LEFT JOIN rpt_mcht_active_info g ON a.mcht_id=g.mcht_id
    WHERE 1=1
    ORDER BY a.mcht_id DESC ) aa
 WHERE 1=1 LIMIT 1,
                 10;

分析:

经过分析,主要慢在如下关联的子查询语句。

代码语言:javascript
复制
 LEFT JOIN
      (SELECT MCHT_ID,
              SUBSTR(MAX(LAST_UPD_DATE_TIME),1,8) audit_dt
       FROM pmp_audit_info
       WHERE AUDIT_STATE='01'
       GROUP BY MCHT_ID) d ON d.mcht_id=a.mcht_id

解决:

  • 5.7版本无窗口函数,8.0版本可尝试通过max() over(partition by)的方式进行改写消除子查询
  • 如业务允许,可增加额外条件如时间字段限制数据量
  • 子查询进行如下改写后,分页查询2s左右,但是业务想全量查询,还是出不来结果
代码语言:javascript
复制
 LEFT JOIN pmp_audit_info d ON d.mcht_id=a.mcht_id
    AND d.AUDIT_STATE='01'
    AND d.LAST_UPD_DATE_TIME=
      (SELECT max(dd.LAST_UPD_DATE_TIME)
       FROM pmp_audit_info dd
       WHERE d.mcht_id=dd.mcht_id)

分析执行计划如下:

image-20210225092705468
image-20210225092705468

d表检索出索引可用但并未用到索引,有warnings产生如下:

代码语言:javascript
复制
 Warning | 1739 | Cannot use ref access on index 'idx_pmp_audit_info_mchtid' due to type or collation conversion on field 'MCHT_ID'

可能是字段类型不一致或者collation不一致,检查后为后者

image-20210225092826820
image-20210225092826820
image-20210225092939120
image-20210225092939120

修改pmp_audit_info这张表的mcht_id字段collation

代码语言:javascript
复制
 ALTER TABLE pmp_audit_info MODIFY mcht_id VARCHAR(32) COLLATE utf8_bin;

重新解析执行计划:

image-20210225093353482
image-20210225093353482

优化后分页查询毫秒级,全量查询秒级(除特殊场景不建议全量查询,最好有范围查询)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档