簡體   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