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

fab29556cfe9ff2bad59122ddc05507b.png

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

问题描述 :distinct的使用可能导致SQL的性能下降,也可能是distinct和group 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)de6784b9dcb0109af1ebd3c5428a30e1.png

27063723822496dad05de384bed7f13c.png

后来需求需要多个组织在一行显示,于是对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的

5047f6a39115c4865f784a5b8b266dc5.png

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

03180466bf66e789918b75a401d156a9.png

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

于是把distinct去掉试试,可能distinct和group 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;
009d968b7ec71e1eafc9675ea0141d9e.png

果然,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)

b079204b2598964fceae7aa6299497b5.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值