記一次 DISTINCT 導(dǎo)致的 SQL 效率問題

來源 |?blog.csdn.net/ol950919/article/details/108052642
問題描述 :distinct的使用可能導(dǎo)致SQL的性能下降,也可能是distinct和group by一起使用的原因
場(chǎng)景 :查詢有多個(gè)組織的人員數(shù)據(jù),人員在a表有多個(gè)組織,所以查詢出來是多行記錄
數(shù)據(jù)量: a表65W+數(shù)據(jù),b表54W+數(shù)據(jù),c表54W+數(shù)據(jù),d表4W+數(shù)據(jù),e表8000+數(shù)據(jù)
下圖SQL會(huì)顯示多行數(shù)據(jù),然后再用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'
可以看到索引的級(jí)別都是ref的,還不錯(cuò),查詢速度很快(execution: 253 ms, fetching: 88 ms)

后來需求需要多個(gè)組織在一行顯示,于是對(duì)SQL做了修改,想到可以用 group_concat 函數(shù)來實(shí)現(xiàn)之
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
加了個(gè)函數(shù)并沒有影響到索引級(jí)別,還是ref的

執(zhí)行之,發(fā)現(xiàn)dataGrip一直在轉(zhuǎn)圈圈,結(jié)果一直都出不來

執(zhí)行了大概十分鐘還沒有出來結(jié)果,我取消了,那肯定不能忍受
于是把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;

果然,sql執(zhí)行立馬恢復(fù)正常
問題是解決了,但是并沒有找到相關(guān)的資料,解釋問題產(chǎn)生的原因,大部分文章是比較distinct和group by的性能,也有說distinct是一個(gè) 雙重循環(huán) ,然后比較去重的過程,所以導(dǎo)致性能比較差,所以能用group by就盡量用group by吧
說到這里,先給大家放上一個(gè)鏈接:
1、(Mysql5.7官方手冊(cè)中提及到的關(guān)于優(yōu)化distinct的方法)
https://dev.mysql.com/doc/refman/5.7/en/distinct-optimization.html2、還有一個(gè)優(yōu)化group by的:
https://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html
推薦大家閱讀。
Mysql5.7官方手冊(cè)中提及到的關(guān)于優(yōu)化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.】
推薦閱讀:
世界的真實(shí)格局分析,地球人類社會(huì)底層運(yùn)行原理
不是你需要中臺(tái),而是一名合格的架構(gòu)師(附各大廠中臺(tái)建設(shè)PPT)
企業(yè)IT技術(shù)架構(gòu)規(guī)劃方案
論數(shù)字化轉(zhuǎn)型——轉(zhuǎn)什么,如何轉(zhuǎn)?
企業(yè)10大管理流程圖,數(shù)字化轉(zhuǎn)型從業(yè)者必備!
【中臺(tái)實(shí)踐】華為大數(shù)據(jù)中臺(tái)架構(gòu)分享.pdf
華為如何實(shí)施數(shù)字化轉(zhuǎn)型(附PPT)
超詳細(xì)280頁(yè)Docker實(shí)戰(zhàn)文檔!開放下載
