表A:批次信息表,
表B:實際批次明細表,
Mysql版本:5.6.36
兩表之間的數據體量差異:表B是表A的10000倍。
經過結轉,表B通常保留 1千5百萬數據。表A就是1千多條數據。
計算近24小時時段,24個批次中最大的一批。由於指標量是每天隨時間推移而變大,因此需要取每個小時最后一批,即是該時段最終指標。減去上一小時指標量即為當前時段內的指標考核量。
原SQL邏輯是 先用兩個表A左連接,連接時將批次時間的Hour + 1使批次正好錯一個小時。得到當前時段與上一時段的批次。
再與表B關聯,得到兩個24批的實際明細,此處將大表表B,關聯了兩次,前面描述,表B數據量在1500萬。導致最終查詢時間在50S左右。
修改后的方式:
使用子查詢,先找出第一個24小時時段的明細數據,大概在3萬左右數據。再用第二個子查詢找出時段錯1個小時的25批明細數據。最后將兩個子查詢使用 hour + 1的方式進行left join。由於子查詢提前過濾了數據量,最終查詢相應時間縮短至 700ms左右。超出預期。達到優化目的。
當然,此處不是即席查詢應用,而是離線worker,700ms 相比較於 50S提升當然是非常可觀的,對於支持實時相應的查詢,200ms以上的可能都要考慮其他方式進行優化了。
由於涉及數據保密,此處不對具體分析過程進行拆解,僅是思路。在大表關聯時盡可能提前縮小數據掃描范圍,有時候子查詢並不一定總是降低效率,這點在HIVE-SQL中體現尤為明顯。