我有一个查询,如下所示:
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;如您所见,这个查询中有三个表
1)vmi_segment_customer_relation,Index:"IDX1_SEGMENT" on "segment_id"列。
2)vmi_factcustomer,Index:"IDX1_F" on "customer_num"列。
3)vmi_dimcustomer,Index:"IDX_CUSTNUM" on "customer_num"列。
所有表的statistics都是最新的,没有过时的统计数据。我使用这个提示获得了这个查询的真正execution plan,如下所示,如下所示:

我对这个计划有一些疑问:
operation-10在operation-11下面(op-10是op-11的子级),因为'IDX_CUSTNUM'索引是用于'MI_DIMCUSTOMER'表的!例如,看看op-5 and op-6。或者是op-8 and op-9,我希望我们的op-10和op-11完全一样,而且不知道为什么不是!Nested loop joins呢?每个嵌套循环的作用是什么?提前感谢
发布于 2022-01-09 20:04:30
您似乎给操作ID分配了太多的意义,它只是为了唯一地标识每个操作,而与操作执行的顺序无关。
您需要阅读计划“内翻”,从最嵌套的操作到嵌套较少的操作。考虑到这一点,让我们看看发生了什么:
IDX1_SEGMENT以检索匹配段的ROWIDs。MI_SEGMENT_CUSTOMER_RELATION中的行由ROWID读取,以筛选与EFFECTIVE_DATE条件匹配的行并获得CUSTOMER_NUM。CUSTOMER_NUM值进行循环。IDX1_F以找到与Op.5中的CUSTOMER_NUM匹配的条目,并检索相应的ROWIDs。MI_FACTCUSTOMER中的行由ROWID读取,以筛选与EFFECTIVE_DATE条件匹配的行并获得CUSTOMER_NUM。CUSTOMER_NUM值进行循环。IDX_CUSTOMER中取ROWIDs匹配的客户号。ROWIDs从作品10循环。MI_DIMCUSTOMER以获取所需的列。显然,这些循环是同时执行的:一旦Op.5中的新值可用,就会进行下一次Ops迭代。9和8可以继续进行,一旦完成,就可以进行操作的下一次迭代。10和11可以获取所需的数据。
考虑到行数较少,并且存在有用的索引,嵌套循环连接的选择似乎是合适的。
https://dba.stackexchange.com/questions/305852
复制相似问题