Mysql優化系列之——優化器對子查詢的處理

sqysl發表於2020-01-21


根據子查詢的型別和位置不同,mysql優化器會對查詢語句中的子查詢採取不同的處理策略,其中包括改寫為連線(join),改寫為半連線(semi-join)及進行物化處理等。

    1. 標量子查詢(Scalar Subquery):查詢語句中的標量子查詢每次只返回一行資料,執行期間優化器能將其優化掉並對其進行緩衝處理。
    2. IN子查詢(唯一)(IN Subquery(Unique)):查詢語句中的子查詢返回唯一資料集,因此,優化器可以將這種子查詢安全的轉換為內連線(inner join)進行處理。explain後執行show warnings應該可以看到這種場景的發生。
    3. IN子查詢(非唯一)(IN Subquery(Non-Unique)):當查詢語句中的子查詢返回非唯一資料集時,此時,優化器並不能將子查詢安全的轉換為內連線,而只能採取其他的處理策略,例如:將子查詢轉換為半連線(Semi-join),而mysql中,執行半連線的策略包括FirstMatch,Materializelookup,Materializescan,DuplicatesWeedout,Loosescan等,每種策略的具體處理細節,大家可以參考相應文件,此處不再贅述。
    4. NOT IN子查詢(NOT IN子查詢):針對查詢語句中的NOT IN子查詢,mysql優化器可以採取物化處理和轉化為exists兩種策略。
    5. 驅動表(Derived Table):針對查詢語句from子句中的子查詢,mysql優化器並不會對其進行物化處理。而是通常對其進行合併處理(merge),其類似於檢視將其定義與查詢語句的謂詞合併的方法。
    6. CTEs和檢視(CTEs and Views):檢視作為儲存的查詢,可以簡化應用,也可以實現資料安全,而CTEs與檢視類似,只是其生命期僅僅侷限於相關查詢語句本身。mysql優化器對CTEs和檢視的處理,主要有兩種策略,那就是合併處理(Merge)和物化處理(Materialize),針對CTEs和檢視,mysql優化器首先嚐試對其進行與主查詢的合併,當某些場景導致其不能與住查詢合併時,才會考慮通過將檢視或CTEs結果通過臨時表進行固化,以供主查詢其他部分進行查詢使用。這點explain後show warings可以看到這些場景的出現。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8484829/viewspace-2674167/,如需轉載,請註明出處,否則將追究法律責任。

相關文章