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