繁体   English   中英

Oracle - Where子句参数改变查询速度

[英]Oracle - Where clause parameter change query speed

使用带有表和视图的查询,但是如果我更改 where 列,速度会发生巨大变化。 可能是什么问题? 很难用谷歌搜索“where 子句的性能变化”,因为所有的例子都不是很接近这个。

SELECT ADRE.*
FROM INVOICE N
INNER JOIN ENTRY_INVOICE NAF
     ON NAF.COMPANY = N.COMPANY
     AND NAF.ID_INVOICE = N.ID_INVOICE
INNER JOIN UV_ENTRY_ALL ADRE
    ON ADRE.COMPANY = NAF.COMPANY
    AND ADRE.ID_ENTRY = NAF.ID_ENTRY
WHERE
    NAF.COMPANY = 1
    /*
    AND NAF.ID_INVOICE = 113806
        => 40 SECONDS
        
    AND  NAF.ID_ENTRY = 387473
        => 0,6 SECONDS
        
    AND EXISTS (SELECT 1 FROM ENTRY_INVOICE WHERE COMPANY = 1 AND ID_INVOICE=113806)
        => 1,6 SECONDS
    */

ENTRY_INVOICE 每张发票最多有 2 条记录。

公司 ID_INVOICE ID_ENTRY
1个 113706 387224
1个 113706 387225
1个 113707 387226
1个 113806 387473

在此处输入图像描述

计划说明https://exists-stack.tiiny.site/

正如所质疑的那样,即使删除表 INVOICE 和 select 特定列,它也不会改变速度。

我会将过滤条件更改为WHERE N.COMPANY = 1以促使优化器将该表用作驱动表。 查询可能如下所示:

SELECT ADRE.*, N.*
FROM INVOICE N
INNER JOIN ENTRY_INVOICE NAF
     ON NAF.COMPANY = N.COMPANY
     AND NAF.ID_INVOICE = N.ID_INVOICE
INNER JOIN UV_ENTRY_ALL ADRE
    ON ADRE.COMPANY = NAF.COMPANY
    AND ADRE.ID_ENTRY = NAF.ID_ENTRY
WHERE
    N.COMPANY = 1 -- changed here

更改后,查询可以从以下索引中受益:

create index ix1 on invoice (company);

create index ix2 on entry_invoice (company, id_invoice);

create index ix3 on uv_entry_all (company, id_entry);

请记住,任何额外的搜索条件都可能影响性能。 特别是,我忽略了查询末尾注释中的谓词。

我会根据您尝试根据条件从中获取数据的相关主表重写查询。 确保有一个在这些情况下最有帮助的索引。 然后加入其他表。 此外,如果处理特定发票的情况,我也会将其添加到 JOIN 子句中。 希望引擎能获得最符合条件的匹配项并以此运行。 在这种情况下,您的 Entry Invoice 表将有两个索引......一个基于公司 + 发票,另一个基于公司 + id 条目。

至于您的发票表,它甚至没有在您的 output 中使用,否则就像查找表一样,所以我将其添加为第二个连接

Table           Index
Entry_Invoice   ( Company, ID_Invoice )
Entry_Invoice   ( Company, ID_Entry )
Invoice         ( Company, ID_Invoice )
UV_Entry_All    ( Company, ID_Entry )

SELECT 
        ADRE.*
    FROM 
        ENTRY_INVOICE NAF
            JOIN UV_ENTRY_ALL ADRE
                ON NAF.COMPANY = ADRE.COMPANY
                AND NAF.ID_ENTRY = ADRE.ID_ENTRY
            -- you dont actually NEED the invoice table here
            INVOICE N
                ON NAF.COMPANY = N.COMPANY
                AND NAF.ID_INVOICE = N.ID_INVOICE
    WHERE
            NAF.COMPANY = 1
        AND
        /*
            NAF.ID_INVOICE = 113806
                 vs
            NAF.ID_ENTRY = 387473
        
            -- dont think this would even be necessary any more
            EXISTS (SELECT 1 FROM ENTRY_INVOICE WHERE COMPANY = 1 AND ID_INVOICE=113806)
        */

UV_ENTRY_ALL 是一个从发票返回所有付款的视图,但是我认为删除一些表会使其性能更好,而且确实如此,但我需要过滤确切的条目。
通过在每个 Union(union all)上添加回ENTRY_INVOICE并返回“ID_INVOICE”,我将其添加到 Join 上,现在就像一个魅力。
另一方面,我在独立运行 UV_ENTRY_ALL 时失去了性能

SELECT ADRE.*
FROM INVOICE N
INNER JOIN ENTRY_INVOICE NAF
    ON NAF.COMPANY = N.COMPANY
    AND NAF.ID_INVOICE = N.ID_INVOICE
INNER JOIN UV_ENTRY_ALL ADRE
   ON ADRE.COMPANY = NAF.COMPANY
   AND ADRE.ID_ENTRY = NAF.ID_ENTRY
   AND ADRE.ID_INVOICE = NAF.ID_INVOICE
WHERE
   NAF.COMPANY = 1 AND NAF.ID_INVOICE = 113806

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM