记一次 DISTINCT 导致的 SQL 效率问题

共 2691字,需浏览 6分钟

 ·

2021-11-08 13:59


来源 | blog.csdn.net/ol950919/article/details/108052642

问题描述 :distinct的使用可能导致SQL的性能下降,也可能是distinctgroup by一起使用的原因

场景 :查询有多个组织的人员数据,人员在a表有多个组织,所以查询出来是多行记录

数据量: a表65W+数据,b表54W+数据,c表54W+数据,d表4W+数据,e表8000+数据

下图SQL会显示多行数据,然后再用distinct去重

select distinct a.ORG_CODE,d.DEPT_NAME,b.PROVINCE_LOGIN_NAME,c.STAFF_CODE,c.STAFF_NAME,e.DICT_DISPLAY POSITION_LEVEL
  from ua_staff_in_position a,ua_account b,ua_organization d,ua_staff c
  left join ua_dict_data e on e.dict_type='POSITION_LEVEL' and e.DICT_VALUE=c.POSITION_LEVEL
 where a.STAFF_CODE=b.STAFF_CODE
   and a.STAFF_CODE=c.STAFF_CODE
   and d.ORG_CODE=a.ORG_CODE
   and a.SET_ID_DEPT='Cm013'

可以看到索引的级别都是ref的,还不错,查询速度很快(execution: 253 ms, fetching: 88 ms)

后来需求需要多个组织在一行显示,于是对SQL做了修改,想到可以用 group_concat 函数来实现之

select distinct a.ORG_CODE,group_concat(d.DEPT_NAME) as DEPT_NAME,b.PROVINCE_LOGIN_NAME,c.STAFF_CODE,c.STAFF_NAME,e.DICT_DISPLAY POSITION_LEVEL
  from ua_staff_in_position a,ua_account b,ua_organization d,ua_staff c
  left join ua_dict_data e on e.dict_type='POSITION_LEVEL' and e.DICT_VALUE=c.POSITION_LEVEL
 where a.STAFF_CODE=b.STAFF_CODE
   and a.STAFF_CODE=c.STAFF_CODE
   and d.ORG_CODE=a.ORG_CODE
   and a.SET_ID_DEPT='Cm013'
 group by a.STAFF_CODE

加了个函数并没有影响到索引级别,还是ref的

执行之,发现dataGrip一直在转圈圈,结果一直都出不来

执行了大概十分钟还没有出来结果,我取消了,那肯定不能忍受

于是把distinct去掉试试,可能distinctgroup by的功能重合了,去掉之后

500 rows retrieved starting from 1 in 657 ms (execution: 552 ms, fetching: 105 ms)

select a.ORG_CODE,group_concat(d.DEPT_NAME) as DEPT_NAME,b.PROVINCE_LOGIN_NAME,c.STAFF_CODE,c.STAFF_NAME,e.DICT_DISPLAY POSITION_LEVEL
  from ua_staff_in_position a,ua_account b,ua_organization d,ua_staff c
  left join ua_dict_data e on e.dict_type='POSITION_LEVEL' and e.DICT_VALUE=c.POSITION_LEVEL
 where a.STAFF_CODE=b.STAFF_CODE
   and a.STAFF_CODE=c.STAFF_CODE
   and d.ORG_CODE=a.ORG_CODE
   and a.SET_ID_DEPT='Cm013'
 group by a.STAFF_CODE;

果然,sql执行立马恢复正常

问题是解决了,但是并没有找到相关的资料,解释问题产生的原因,大部分文章是比较distinctgroup by的性能,也有说distinct是一个 双重循环 ,然后比较去重的过程,所以导致性能比较差,所以能用group by就尽量用group by


说到这里,先给大家放上一个链接:

  • 1、(Mysql5.7官方手册中提及到的关于优化distinct的方法)
    https://dev.mysql.com/doc/refman/5.7/en/distinct-optimization.html

  • 2、还有一个优化group by的:
    https://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html

推荐大家阅读。

Mysql5.7官方手册中提及到的关于优化distinct的方法,原文如下:

MySQL 5.7 Reference Manual / … / DISTINCT Optimization

8.2.1.16 DISTINCT Optimization

DISTINCT combined with ORDER BY needs a temporary table in many cases.】

推荐阅读:

世界的真实格局分析,地球人类社会底层运行原理

不是你需要中台,而是一名合格的架构师(附各大厂中台建设PPT)

企业IT技术架构规划方案

论数字化转型——转什么,如何转?

企业10大管理流程图,数字化转型从业者必备!

【中台实践】华为大数据中台架构分享.pdf

华为的数字化转型方法论

华为如何实施数字化转型(附PPT)

超详细280页Docker实战文档!开放下载

华为大数据解决方案(PPT)


浏览 21
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报