AnalyticDB MySQL版的SQL診斷功能可以對SQL查詢進(jìn)行Query、Stage和算子(Operator)級別的信息統(tǒng)計(jì),再在統(tǒng)計(jì)信息的基礎(chǔ)上進(jìn)行診斷并提供調(diào)優(yōu)建議。本文介紹如何查看和分析算子級別診斷結(jié)果。

診斷結(jié)果類型

說明 查看算子級別診斷結(jié)果的方法,請參見查看診斷結(jié)果

聚合算子聚合度低

  • 問題

    聚合算子的聚合度一般指GROUP BY分組聚合操作中的輸入數(shù)據(jù)量和輸出數(shù)據(jù)量的比值(即InputDataSize和OutputDataSize的比值),該值越小表明聚合度越低,聚合效果越差。在AnalyticDB MySQL版中,分組聚合操作一般分為兩步:初步聚合(PARTIAL)和最終聚合(FINAL)。如果聚合算子分組的個(gè)數(shù)較多,會(huì)導(dǎo)致聚合度低,那么在第一步的初步聚合操作中,不但不能減少網(wǎng)絡(luò)數(shù)據(jù)傳輸,反而會(huì)消耗大量的計(jì)算資源。

  • 建議

    可以考慮跳過初步聚合操作,直接在各個(gè)節(jié)點(diǎn)間對數(shù)據(jù)進(jìn)行重分布,之后直接進(jìn)行一次最終聚合。更多詳情,請參見分組聚合查詢優(yōu)化

過濾條件沒有下推

  • 問題
    AnalyticDB MySQL版在存儲數(shù)據(jù)時(shí)默認(rèn)對表的全部字段創(chuàng)建了索引,您可以在查詢時(shí)使用這些索引來加速數(shù)據(jù)的過濾。但在如下場景中AnalyticDB MySQL版不會(huì)將過濾條件下推:
    • 查詢語句中使用了no_index_columnsfilter_not_pushdown_columnsHint,或集群使用了adb_config filter_not_pushdown_columns配置,導(dǎo)致過濾條件下推功能被關(guān)閉。
    • 過濾條件中使用了函數(shù)(包括cast操作符)。
    • 過濾條件中的相關(guān)字段沒有索引(例如建表時(shí)指定了no_index關(guān)鍵字,或建表后執(zhí)行DROP INDEX刪除了索引)。
  • 建議
    • 如果是查詢語句使用了Hint或集群使用了配置,導(dǎo)致的過濾條件下推功能關(guān)閉,請檢查使用該Hint或配置的原因并判斷是否可以取消該Hint或配置。更多詳情,請參見過濾條件不下推
    • 如果是使用了函數(shù),可以考慮是否直接使用該函數(shù)寫入數(shù)據(jù),而在查詢時(shí)去掉函數(shù)。
    • 如果是過濾條件中的相關(guān)字段沒有索引導(dǎo)致過濾條件沒有下推,那么需要檢查沒有索引的原因。

Join存在數(shù)據(jù)膨脹

  • 問題

    Join的數(shù)據(jù)膨脹率是Join的輸出行數(shù)與Join的輸入行數(shù)的比值,其中Join的輸入行數(shù)為左表行數(shù)與右表行數(shù)之和。對于合理Join條件,一般Join的輸出行數(shù)會(huì)小于輸入行數(shù),如果Join的輸出行數(shù)大于輸入行數(shù),那么會(huì)存在Join數(shù)據(jù)膨脹的問題,Join數(shù)據(jù)膨脹會(huì)導(dǎo)致較多的計(jì)算資源和內(nèi)存資源被占用,導(dǎo)致查詢較慢。

  • 建議
    • 如果是數(shù)據(jù)本身特征導(dǎo)致的Join數(shù)據(jù)膨脹,例如左右表都大量存在的相同的值,可以考慮在表過濾階段將這些相同值都過濾掉不參與Join。
    • 如果是不優(yōu)的Join順序?qū)е碌臄?shù)據(jù)膨脹,可以考慮手動(dòng)調(diào)整Join順序。調(diào)整方法,請參見手動(dòng)調(diào)整Join順序

Join的右表過大

  • 問題
    AnalyticDB MySQL版中的Join右表一般指Builder表,用于構(gòu)建內(nèi)存中的Hash結(jié)構(gòu)或者Set結(jié)構(gòu)。右表過大,可能會(huì)占用較多的內(nèi)存資源,影響集群整體穩(wěn)定性。導(dǎo)致Join右表過大的可能原因如下:
    • SQL中有Left Join。由于Left Join的右表在執(zhí)行過程中必須作為Builder表,所以如果Left Join的右表過大,必然占用較多內(nèi)存資源。
    • AnalyticDB MySQL版在預(yù)估左右表數(shù)據(jù)量時(shí),由于統(tǒng)計(jì)信息過期等原因?qū)е鹿烙?jì)錯(cuò)誤。
  • 建議

    建議將Left Join優(yōu)化改寫成Right Join。改寫方法,請參見Left Join優(yōu)化改寫為Right Join

存在Cross Join

  • 問題

    Cross Join,即沒有Join條件的Join操作,輸出的行數(shù)是左右兩表行數(shù)的乘積。如果左右表都較大,會(huì)極大地影響AnalyticDB MySQL版集群的穩(wěn)定性。

  • 建議

    考慮增加Join條件,消除Cross Join。

掃描算子讀取字段個(gè)數(shù)較多

  • 問題

    掃描算子會(huì)在AnalyticDB MySQL版的存儲層進(jìn)行數(shù)據(jù)的過濾和明細(xì)數(shù)據(jù)的讀取,如果SELECT的字段個(gè)數(shù)較多,需要讀取的明細(xì)數(shù)據(jù)也較多,那么就會(huì)占用較大的磁盤I/O資源,影響AnalyticDB MySQL版集群整體穩(wěn)定性。

  • 建議

    可以優(yōu)化SQL語句,減少SELECT語句中不必要的字段。

表掃描數(shù)據(jù)量傾斜

  • 問題

    AnalyticDB MySQL版是分布式執(zhí)行架構(gòu),大表的數(shù)據(jù)一般需要指定分布字段,數(shù)據(jù)寫入時(shí)根據(jù)分布字段分散到不同的存儲節(jié)點(diǎn)上。如果分布字段的值分布不均勻,那么數(shù)據(jù)存儲在各個(gè)節(jié)點(diǎn)上時(shí)也會(huì)不均勻,最終導(dǎo)致數(shù)據(jù)讀取時(shí),各個(gè)節(jié)點(diǎn)在讀取數(shù)據(jù)時(shí)存在時(shí)間上的長尾,影響最終的查詢效果。

  • 建議

    通過選擇合適的分布字段來減少表掃描數(shù)據(jù)量的傾斜。優(yōu)化方法,請參見分布字段合理性診斷

索引不高效

  • 問題

    AnalyticDB MySQL版在使用索引進(jìn)行數(shù)據(jù)過濾時(shí),若需要過濾的字段過濾度(即過濾算子的輸出數(shù)據(jù)量和輸入數(shù)據(jù)量的比值)較低時(shí),使用索引不一定能獲得預(yù)期的過濾效果。

  • 建議

    可以考慮不下推過濾條件,而在計(jì)算節(jié)點(diǎn)中直接執(zhí)行過濾操作。更多詳情,請參見過濾條件不下推