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

 

问题描述 :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)记一次 DISTINCT 导致的 SQL 效率问题_python_02

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

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

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

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

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

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

于是把distinct去掉试试,可能distinct和​​ ​

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;

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

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

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

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