MySQL千萬級多表關聯SQL語句調優

2021-07-26 23:19:55 字數 2598 閱讀 9584

本文不涉及複雜的底層資料結構,通過explain解釋sql,並根據可能出現的情況,來做具體的優化,使千萬級表關聯查詢第一頁結果能在2秒內完成(真實業務告警系統優化結果)。

需要優化的查詢:使用explain

出現了using temporary;

有分頁時出現了using filesort則表示使用不了索引,需要根據下面的技巧來調整語句

rows過多,或者幾乎是全表的記錄數;

key 是 (null);

possible_keys 出現過多(待選)索引。

1.使用explain語法,對sql進行解釋,根據其結果進行調優:

a.explain 結果中,第一行出現的表就是驅動表

b.對驅動表可以直接排序,對非驅動表(的字段排序)需要對迴圈查詢的合併結果(臨時表)進行排序(important!),即using temporary;

c. [驅動表] 的定義為:1)指定了聯接條件時,滿足查詢條件的記錄行數少的表為[驅動表];2)未指定聯接條件時,行數少的表為[驅動表](important!)。

d.優化的目標是盡可能減少join中nested loop的迴圈次數,以此保證:永遠用小結果集驅動大結果集(important!)!:a join b,a為驅動,a中每一行和b進行迴圈join,看是否滿足條件,所以當a為小結果集時,越快。

e.nestedloopjoin實際上就是通過驅動表的結果集作為迴圈基礎資料,然後一條一條的通過該結果集中的資料作為過濾條件到下乙個表中查詢資料,然後合併結果。如果還有第三個參與join,則再通過前兩個表的join結果集作為迴圈基礎資料,再一次通過迴圈查詢條件到第三個表中查詢資料,如此往復

2.兩表join優化:

a.當無order by條件時,根據實際情況,使用left/right/inner join即可,根據explain優化 ;

b.當有order by條件時,如select * from a inner join b where 1=1 and other condition order by a.col;使用explain解釋語句;

1)如果第一行的驅動表為a,則效率會非常高,無需優化;

2)否則,因為只能對驅動表字段直接排序的緣故,會出現using temporary,所以此時需要使用straight_join明確a為驅動表,來達到使用a.col上index的優化目的;或者使用left join且where條件中不含b的過濾條件,此時的結果集為a的全集,而straight_join為inner join且使用a作為驅動表

3.多表join優化:

a.無order by條件時,根據實際情況,使用left/right/inner join即可,根據explain優化;

b.有order by a.col條件時,所有join必須為left join,且每個join欄位都建立索引,同時where條件中只能有a表的條件,即將其它表的資料關聯到a中形成一張大表,再對a的全集進行過濾;

如果不能全使用left join,則需靈活使用straight_join及其它技巧,以時間排序為例:

1)資料入庫按照平台時間入庫,自然a的資料都按時間有序;

select c.*, r.hypervisor_host_name hostname, r.host_ip from trust_monitor cstraight_joinres_node r on c.res_node_id = r.idstraight_joinam_assets a on r.asset_id = a.id and a.status = 58straight_joinse_role s on a.dept_flag = s.role_org and s.role_id in (32,33,36,41) where c.status = 58 and c.changed_type = 79 limit 1,10;

select c.*, r.hypervisor_host_name hostname, r.host_ip from trust_monitor cinner joinres_node r on c.res_node_id = r.idinner joinam_assets a on r.asset_id = a.id and a.status = 58inner joinse_role s on a.dept_flag = s.role_org and s.role_id in (32,33,36,41) where c.status = 58 and c.changed_type = 79order by c.changed_timelimit 1,10;

兩者結果一致

4.誤區:

a.檢視只是遮蔽或者高效集合多表資料的一種方法,檢視與表join,不會起到任何效果

參考:

MySQL百萬級 千萬級資料多表關聯SQL語句調優

mysql百萬級 千萬級資料多表關聯sql語句調優 本文不涉及複雜的底層資料結構,通過explain解釋sql,並根據可能出現的情況,來做具體的優化,使百萬級 千萬級資料表關聯查詢第一頁結果能在2秒內完成 真實業務告警系統優化結果 希望讀者能夠理解sql的執行過程,並根據過程優化,走上自己的 成金之...

MySQL百萬級 千萬級資料多表關聯SQL語句調優

本文不涉及複雜的底層資料結構,通過explain解釋sql,並根據可能出現的情況,來做具體的優化,使百萬級 千萬級資料表關聯查詢第一頁結果能在2秒內完成 真實業務告警系統優化結果 希望讀者能夠理解sql的執行過程,並根據過程優化,走上自己的 成金之路 需要優化的查詢 使用explain 出現了usi...

sql 多表關聯

專案中遇到多表關聯查詢,device info與device oper是一對多關係,project info,branch info與device info是一對多關係。多表的查詢 select o.d.devicename,p.projectname,b.branchname r.releasei...