首页 > 解决方案 > 由于日期过滤器使其运行缓慢而需要优化的 Oracle 查询

问题描述

我有一个查询需要优化并且需要帮助。查询需要不可接受的时间才能完成。

这是查询的通用形式(从早期更新):

WITH

    SQ_Filter_Date AS
    (
        SELECT DISTINCT
            Business_Day AS Filter_Business_Day
        FROM
            Table_A
        WHERE
            Load_Date BETWEEN TO_DATE( '2019-11-01', 'yyyy-mm-dd' ) AND TO_DATE( '2019-12-01', 'yyyy-mm-dd' )
    ),

    SQ_Table_A_Results AS
    (
        SELECT *
        FROM
            Table_A sr INNER JOIN SQ_Filter_Date sfd ON ( sr.Business_Day = sfd.Filter_Business_Day )
    ),

    SQ_Final AS
    (
        SELECT *
        FROM
            SQ_Table_A_Results a 
            JOIN Table_B b ON ( a.A_Source_Key = b.B_Source_Key )
            JOIN Table_C c ON ( a.A_Type_Key = c.C_Type_Key )
            JOIN Table_D d ON ( a.A_Business_Type_Key = d.D_Business_Type_Key )
    )

SELECT *
FROM
    SQ_Final

Table_A 有一个作为主键的索引列。Table_A 也按 Business_Day 进行分区。因此,如果我们在 Business_Day 上进行过滤,那就没问题了。问题是我们需要过滤一个名为 Load_Date 的未索引列。我已经检查过了,由于我无法控制的事情,我们不允许向该列添加索引。

那么如何修改这个查询以更快地运行呢?

标签: sqloracleoptimization

解决方案


您可以避免(可能)昂贵DISTINCT的费用,但不知道在不知道基数和索引的情况下它是否会更快

WITH
    SQ_Table_A_Results AS
    (
        SELECT *
        FROM
        Table_A sr 
        WHERE EXISTS (
             SELECT * FROM Table_A F
             WHERE F.Load_Date BETWEEN 
             TO_DATE( '2019-11-01', 'yyyy-mm-dd' ) 
             AND 
             TO_DATE( '2019-12-01', 'yyyy-mm-dd' )
             AND F.Business_Day  = sr.Business_Day
        )

SELECT *
FROM
    SQ_Table_A_Results a 
    JOIN Table_B b ON ( a.A_Source_Key = b.B_Source_Key )
    JOIN Table_C c ON ( a.A_Type_Key = c.C_Type_Key )
    JOIN Table_D d ON ( a.A_Business_Type_Key = d.D_Business_Type_Key )

你也会有更少的列


推荐阅读