我有两个查询看起来很接近,但 Oracle 的性能却大不相同。
查询 A
Create Table T1 as Select * from FinalView1 where CustomerID in ('A0000001','A000002')
查询 B
Create Table T1 as Select * from FinalView1 where CustomerID in (select distinct CustomerID from CriteriaTable)
CriteriaTable 有 800 行,但都属于客户 ID 'A0000001' 和 'A000002'。这意味着子查询:“select distinct CustomerID from CriteriaTable”也只返回与查询 A 中手动输入的相同的两个元素('A0000001'、'A000002')
以下是FinalView1下的查询
create or replace view FinalView1_20200716 as
select
Customer_ID,
<Some columns>
from
Table1_20200716 T1
INNER join Table2_20200716 T2 on
T1.Invoice_number = T2.Invoice_number
and
T1.line_id = T2.line_id
left join Table3_20200716 T3 on
T3.id = T1.Customer_ID
left join Table4_20200716 T4 on
T4.Shipping_ID = T1.Shipping_ID
left join Table5_20200716 Table5 on
Table5.Invoice_ID = T1.Invoice_ID
left join Table6_20200716 T6 on
T6.Shipping_ID = T4.Shipping_ID
left join First_Order first on
first.Shipping_ID = T1.Shipping_ID
;
Table1_20200716、Table2_20200716、Table3_20200716、Table4_20200716、Table5_20200716、Table6_20200716 是具有时间有效性特征的对应表的视图。例如
Table1_20200716下的查询创建或替换视图Table1_20200716为
select
*
from Table1 as for period of to_date('20200716,'yyyymmdd')
但是表“First_Order”只是一个普通表
以下是两个查询的性能(根据解释计划):
查询一:
基数:102 成本:204
总运行时间:最长 5 秒
查询 B:
基数:27921981
费用:14846
总运行时间:20 分钟直到用户取消
所有表都使用那些用于连接 FinalView1 中其他表的列进行索引。根据说明计划,除了FirstOrder 表之外,它们都已被使用。
查询 A 使用 FirstOrder 表上的唯一索引,而查询 B 执行完整扫描。
对于查询 B,我期望 Oracle 会在执行主查询之前先查询子查询将结果放入 in 运算符,因此对性能的影响应该很小。
提前致谢!