Oracle
儘管在主查詢中使用了兩個內部聯接,但執行計劃中的三個“嵌套循環聯接”
我有一個查詢,如下所示:
with cte as (select customer_num from vmi_segment_customer_relation where effective_date = to_date('12/30/2021', 'mm/dd/yyyy') and segment_id = 10000000592 ) select t.customer_num, cust_first_name, cust_last_name, cust_type_desc from vmi_factcustomer t join cte f on t.customer_num = f.customer_num and t.effective_date = to_date('12/30/2021', 'mm/dd/yyyy') join vmi_dimcustomer d on t.customer_num = d.customer_num;
如您所見,此查詢中有三個表
vmi_segment_customer_relation
、索引:"IDX1_SEGMENT"
在"segment_id"
列上。
vmi_factcustomer
、索引:"IDX1_F"
在"customer_num"
列上。
vmi_dimcustomer
、索引:"IDX_CUSTNUM"
在"customer_num"
列上。所有表
statistics
都是最新的,並且沒有過時的統計資訊。我execution plan
使用這個提示得到了這個查詢的真實資訊/*+gather_plan_statistics*/
,你可以看到這裡是計劃:我對計劃有一些疑問:
- 我希望在
operation-10
(operation-11
op-10 是 op-11 的子項)下,因為'IDX_CUSTNUM'
索引是針對'MI_DIMCUSTOMER'
table 的!看看op-5 and op-6
例子。或者op-8 and op-9
,我希望 op-10 和 op-11 完全像這兩個一樣,但不知道為什麼不是!- 另一個問題是,查詢中有兩個連接,為什麼我們
Nested loop joins
在計劃中看到三個?每個嵌套循環的作用是什麼?提前致謝
您似乎為操作 ID 賦予了太多意義。它只是用來唯一標識每個操作,與操作執行的順序無關。
您需要“從裡到外”閱讀計劃,從最嵌套的操作到嵌套較少的操作。考慮到這一點,讓我們看看發生了什麼:
- 作品。6.
IDX1_SEGMENT
被掃描以檢索ROWID
匹配該段的s。- 作品。5.
MI_SEGMENT_CUSTOMER_RELATION
讀取from 的行ROWID
以過濾符合EFFECTIVE_DATE
條件的行並獲取CUSTOMER_NUM
。- 作品。3. 循環檢索到的
CUSTOMER_NUM
值。- 作品。9. 在循環
IDX1_F
中掃描以查找與CUSTOMER_NUM
Op. 匹配的條目。5,並ROWID
檢索到對應的s。- 作品。8.
MI_FACTCUSTOMER
讀取from 的行ROWID
以過濾符合EFFECTIVE_DATE
條件的行並獲取CUSTOMER_NUM
。- 作品。2. 循環
CUSTOMER_NUM
來自 Op. 的值。8.- 作品。10. 在循環中訪問匹配客戶編號的
IDX_CUSTOMER
fetch s。ROWID
- 在。
ROWID
1.從 Op走過s。10.- 作品。11. 在循環訪問
MI_DIMCUSTOMER
中獲取所需的列。顯然,這些循環是同時執行的:只要來自 Op. 的新值。5 可用,是 Ops 的下一次迭代。9 和 8 可以繼續,一旦完成,Ops 的下一次迭代。10 和 11 可以獲取所需的數據。
鑑於行數較少且存在有用的索引,嵌套循環連接的選擇似乎是合適的。