本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Aurora DSQL EXPLAIN 計劃中的批次巢狀迴圈聯結
當查詢將小型外部輸入聯結到 Aurora DSQL 可以從儲存有效率地掃描的內部輸入時,Aurora DSQL 可以選擇Nested Loop (Batched Join)計劃。此聯結類型可在探查內部之前將多個外部資料列分組在一起,以減少運算和儲存層之間的往返。
標準巢狀迴圈一次處理一個外部資料列,並再次為每個資料列執行內部掃描。批次巢狀迴圈聯結會收集一批外部資料列、建置整個批次的內部掃描工作,然後將傳回的內部資料列聯結回相符的外部資料列。
批次巢狀迴圈聯結的運作方式
-
Aurora DSQL 會從聯結的外部讀取一批資料列。
-
如果內部端是
Index Scan或 ,並在外部端Index Only Scan使用Index Cond參數化 ,Aurora DSQL 會繫結每個外部資料列的條件,並將產生的索引掃描金鑰合併為一個批次內部掃描。其他聯結述詞不會驅動內部掃描。 -
Index Scan或Index Only Scan沒有外部參數化Index Cond的行為類似於Full Scan或Sequential Scan。Aurora DSQL 沒有參數化索引掃描金鑰,可合併每個外部批次執行一次內部掃描,而非每個外部資料列執行一次內部掃描。 -
Aurora DSQL 會在資料列到達批次時從內部串流資料列。在加入之前,不會具體化批次的整個內部結果。
-
當內部
Index Scan或Index Only Scan具有外部參數化 時Index Cond,Aurora DSQL 會使用Recheck Cond將每個傳回的內部資料列比對回批次中適用的外部資料列。Aurora DSQL 接著會套用任何剩餘的聯結述詞。如果沒有外部參數化Index Cond,Aurora DSQL 會直接套用聯結述詞,因為它會比對每個串流的內部資料列與外部批次。 -
對於左側和反聯結,Aurora DSQL 會追蹤哪些外部資料列相符,並在批次的內部掃描完成後發出不相符的資料列。
當內部是具有參數化 的索引掃描時,這種方法最有用Index Cond,因為合併的掃描金鑰提供整個外部批次的目標儲存存取權。
當 Aurora DSQL 使用此聯結時
當聯結的內側是實體掃描節點時,Aurora DSQL 會考慮批次巢狀迴圈聯結,這表示 Index Scan、Full Scan、 Index Only Scan或 Sequential Scan,且批次處理的成本預期低於為每個外部資料列執行內部掃描的成本。實際上,最大效益通常來自較小的外部輸入和內部索引掃描,其外部具有Index Cond參數化。
如果另一個計劃形狀更便宜,例如雜湊聯結或合併聯結,Aurora DSQL 會改為選擇該計劃。若要在調校期間比較計劃形狀,您可以停用目前工作階段的批次巢狀迴圈聯結:
SET dsql.enable_batched_nestloop = off;
如何讀取批次巢狀迴路聯結輸出
下列查詢使用來自 的範例transaction和account資料表讀取 Aurora DSQL EXPLAIN 計劃:
EXPLAIN SELECT t.account_id, a.balance FROM transaction t LEFT JOIN account a ON t.account_id = a.customer_id AND a.balance > CASE WHEN t.description LIKE 'fee%' THEN 0 ELSE 100 END WHERE t.transaction_date >= '2025-01-01' AND (a.status = 'active' OR a.customer_id IS NULL) ORDER BY t.account_id;
EXPLAIN 計劃可以包含類似下列的輸出:
Sort
Sort Key: t.account_id
-> Nested Loop (Batched Join)
Filter: (((status)::text = 'active'::text) OR (customer_id IS NULL))
Join Type: Left
Recheck Cond: (customer_id = t.account_id)
Join Filter: (balance > CASE WHEN (t.description ~~ 'fee%'::text) THEN '0'::numeric ELSE '100'::numeric END)
-> Full Scan (btree-table) on transaction t
-> Storage Scan on transaction t
Filters: (transaction_date >= '2025-01-01 00:00:00'::timestamp without time zone)
-> B-Tree Scan on transaction t
-> Index Only Scan using idx1 on account a
Index Cond: (customer_id = t.account_id)
Nested Loop (Batched Join)-
顯示 Aurora DSQL 在探測聯結的內側之前,正在批次處理外部資料列。
Index Cond-
顯示用來探測目前批次內部的述詞。當內側是
Index Scan或 時Index Only Scan,此述詞通常會參考聯結外側的資料欄。 Filter-
顯示套用至聯結結果的條件。在此範例中,
WHERE (a.status = 'active' OR a.customer_id IS NULL)條件會顯示在此處。在標準 SQL 左聯結語意下,無法將此條件推送至內部掃描,因為這樣做會變更查詢結果。Aurora DSQL 會在聯結節點上將其顯示為篩選條件。相反地, 上的 條件只會t.transaction_date參考外部資料表,因此會出現在外部實體掃描下方。 Join Type-
顯示批次聯結的聯結語意,例如
Left、Semi或Anti。 Recheck Cond-
只有在內部端是
Index Scan或在聯結的外部Index Only Scan具有至少一個Index Cond參數化的 或 時才會出現。對於每個傳回的內部資料列,Aurora DSQL 會針對批次中的每個外部資料列執行重新檢查,以判斷哪些外部資料列產生該探查,並應該與該內部資料列聯結。 Join Filter-
顯示 Aurora DSQL 在將內部資料列比對回批次中的候選外部資料列後評估的聯結述詞。這些述詞會影響哪些資料列對聯結,但它們不會像
Index Cond這樣驅動儲存探查。 - 先前的排序節點
-
當查詢需要排序輸出時,可能會出現 。批次巢狀迴圈聯結不會保留與標準巢狀迴圈相同的輸出順序保證,因此 Aurora DSQL 可以在傳回最終結果集之前新增明確的排序。