[英]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.