Sql 需要优化的Oracle查询,因为日期筛选器使其运行缓慢

Sql 需要优化的Oracle查询,因为日期筛选器使其运行缓慢,sql,oracle,optimization,Sql,Oracle,Optimization,我有一个需要优化的查询,需要帮助。查询需要花费不可接受的时间才能完成 以下是先前更新的查询的通用形式: WITH SQ_Filter_Date AS ( SELECT DISTINCT Business_Day AS Filter_Business_Day FROM Table_A WHERE Load_Date BETWEEN TO_DATE( '2019-

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

以下是先前更新的查询的通用形式:

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
表A的索引列是主键。表A也按工作日划分。因此,如果我们在工作日进行过滤,那么就没有问题了。问题是我们需要对一个名为Load_Date的未索引列进行筛选。我已经检查过了,由于我无法控制的原因,我们不允许向该列添加索引

那么,如何修改此查询以更快地运行?

看看这是否有帮助:

WITH 
SQ_Filter_Date AS
(
    SELECT 
        A_Business_Type_Key, 
        MIN(LOAD_DATE) as MIN_LOAD_DATE,
        MAX(LOAD_DATE) as MAX_LOAD_DATE
    FROM
        Table_A
    GROUP BY
        A_Business_Type_Key

),
SQ_Table_A_Results AS
(
    SELECT A_Business_Type_Key
    FROM
        SQ_Filter_Date
    WHERE
    *-- << 
    --   have the date check here - 
    --   i dont whether this check is complete 
    --   so change it according to your needs 
    -- >>* 
    MIN_LOAD_DATE BETWEEN TO_DATE( '2019-11-01', 'yyyy-mm-dd' ) AND TO_DATE( '2019-12-01', 'yyyy-mm-dd' )
    or MAX_LOAD_DATE BETWEEN TO_DATE( '2019-11-01', 'yyyy-mm-dd' ) AND TO_DATE( '2019-12-01', 'yyyy-mm-dd' )
    
),
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

您可以使用此方法避免可能昂贵的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 )

您也将有更少的列

我选中了,并且它不是在加载日期创建索引的选项。-这是什么意思?您不能添加索引吗?如果是,为什么?你怎么知道是日期过滤器导致了速度慢,而不是连接?这里有一种方式,你可以告诉我,一种方式或另一种方式。仅从表_A中选择数据,并在其上设置日期过滤器无连接。那也很慢吗?如果不是,那么你的猜测可能是错的。无论如何,这会让你专注于真正缓慢的事情。在同一个优化问题中,无需将联接与单个表上的日期筛选器混淆。您联接的值是否唯一?@stickybit,dba通知我,我们无法添加其他索引。所以不幸的是,这不是一个选项,我不能改变它。@mathguy,你是对的。我尝试了你所说的,问题是对表_D的列的连接。但是正确的结果集需要该连接。那么我该如何解决这个问题呢?我不认为这在功能上是等价的,因为这会在工作日出现“漏洞”