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



使用一个带有表和视图的查询,但是如果我更改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条记录。

COMPANYID_INVOICEID_ENTRY
1113706387224
1113706387225
1113707387226
1113806387473

我会将筛选条件更改为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子句中。希望引擎能达到最佳匹配标准,并以此运行。在这种情况下,输入发票表将有两个索引。。。一个是基于公司+发票,另一个是根据公司+id条目。

至于你的发票表,它甚至没有在你的输出中使用,否则就像查找表一样,所以我添加了它作为第二个加入

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

最新更新