在 "In" orperator 中使用子查询的 Oracle 性能问题

Oracle Performance issues on using subquery in an "In" orperator

我有两个看起来很相似的查询,但 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)

条件Table 有 800 行,但全部属于客户 ID 'A0000001' 和 'A000002'。 这意味着子查询:"select distinct CustomerID from CriteriaTable" also only returns the same two elements('A0000001','A000002') 在查询 A

中手动输入

以下是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是对应table的浏览量具有时间有效性特征。例如

Table1_20200716下的查询 创建或替换视图 Table1_20200716 为

select
*
from Table1 as for period of to_date('20200716,'yyyymmdd')

然而 table “First_Order” 只是一个普通的 table as

以下是两个查询的性能(根据解释计划):

查询A:

基数:102 费用:204

总运行时间:最多 5 秒

查询 B:

基数:27921981

费用:14846

用户取消前总共 Runtime:20 分钟

所有 tables 都使用那些用于与 FinalView1 中的其他 tables 连接的列进行索引。根据explain plan,除了FirstOrdertable.

,其他都用过了

查询 A 在 FirstOrder Table 上使用了唯一索引,而查询 B 执行了完整扫描。

对于查询B,我原以为Oracle会先查询子查询,将结果放入in运算符,然后再执行主查询,因此对性能的影响应该很小。

提前致谢!

正如我 2 天前的评论中提到的。有人实际上 post 编辑了解决方案,然后在答案实际有效时将其删除。等了 2 天后,我设计了 post 那个解决方案。

该解决方案表明“in”运算符降低了性能。并建议我用内部连接替换它

Create Table T1 as 
Select 
    FV.* 
from 
    FinalView1 FV 
    inner join (
        select distinct 
            CustomerID 
        from 
            CriteriaTable
    ) CT on CT.customerid = FV.customerID;

解释计划的结果比以前差: Cardinality:28364465(来自 27921981) 成本:15060(从 14846)

然而,它只需要 17 秒。非常好!