加入 2 个脚本 ORACLE 时的 SQL 性能
Posted
技术标签:
【中文标题】加入 2 个脚本 ORACLE 时的 SQL 性能【英文标题】:SQL Performance on joining 2 scripts ORACLE 【发布时间】:2017-09-06 08:20:16 【问题描述】:我有两个脚本,很复杂,一个是我自己写的,另一个是 10 年前写的。第一个脚本获取必要的 id 并在大约 30 秒内执行,例如:
| ID | some other info ...
+----+--------------------
| 1 | ...
| 2 | ...
| 3 | ...
| 4 | ...
第二个脚本获取的是一些比较复杂的数据,是通过很多子查询计算出来的,执行时间大概在30秒左右,例如:
| ID | Computed Info
+----+--------------------
| 1 | 111
| 2 | 222
| 3 | 333
| 4 | 444
现在我的 script1 需要包含来自 script2 的部分结果,因为 script2 非常复杂,很难分解必要的部分,这就是为什么我尝试使用 ID 将 script2 的连接结果留给 script1
SELECT TABLE1.*, TABLE2.COMPUTED_INFO FROM SCRIPT1 TABLE1 LEFT JOIN SCRIPT2 TABLE2 ON TABLE2.ID = TABLE1.ID
我得到的结果也是预期的结果是:
| ID | some other info ... | Computed Info
+----+---------------------+---------------
| 1 | ... | 111
| 2 | ... | 222
| 3 | ... | 333
| 4 | ... | 444
问题是在加入他们两个之后,执行时间现在是 20+ 分钟。
我也试过了
with table1 as
(script1),
table2 as
(script2)
select t1.*, t2.computed_data
from table1 t1 left join table2 t2 on t2.id = t1.id
这导致了 10+ 分钟。 我想知道为什么会发生这样的事情,当绝对 script1 和 script2 分别在大约 30 秒内分别运行时,但是当一起运行时,运行时间高达 10+ 还有其他方法可以实现吗?
【问题讨论】:
您是否尝试过在查询中运行EXPLAIN PLAN?输出是什么? @markusk 我没有,应该知道 @markusk 对于有问题的脚本2 我没有得到任何结果,并得到错误,指出超出了空间配额,对于它执行的脚本1,我应该从 plan_table 中注意哪一列?跨度> 有趣的部分不是script1
和script2
的单独执行计划,而是连接的执行计划。我怀疑您的问题是由script1
和script2
返回的大量行以及没有索引引起的。如果您可以display the explain plan 并将输出复制到您的问题中,那将有助于分析您的问题。
【参考方案1】:
您可以在加入这些表之前创建临时表。
首先创建表temp1 as select * from script1
并创建表 temp2 作为 select * from script2
然后选择您的查询
SELECT temp1.*, temp2.COMPUTED_INFO FROM temp1 TABLE1 LEFT JOIN temp2 TABLE2 ON temp2.ID = temp1.ID
【讨论】:
我对临时表进行了一些研究,似乎我需要定义它们一次,并且在需要时它们会被每个会话填充。我想知道是否可以避免使用临时表,并在 sql 查询中执行所有操作,或者至少是什么原因导致时间增加,因为 script1 在 x 时间实现,而 script2 在 y 时间实现,为什么我不能在 x+y 时间获得性能? 你能看到解释计划吗?如果你加入这些脚本,它有不同的解释计划。也许您可以尝试使用带有物质化提示的语句 我尝试为脚本创建临时表,但是将数据插入临时表需要 20 分钟,而简单地执行脚本大约需要 30 秒,我错过了什么吗? 你在运行选择查询时丢失了它并没有带来所有数据,例如在 toad 中它带来 500 行,所以它可能很快但所有数据都不是 一开始我也有类似的想法,但是script2返回的只有600+行,而script1返回45【参考方案2】:上次遇到此类问题时,我使用临时表解决了它。我用 SCRIPT1 和 SCRIPT2 结果创建了临时表。然后将索引添加到 ID 列。
在此之后,与您的查询类似的查询必须执行得更快。
这发生在 postgresql 服务器上,但问题的根源是相同的。通常,RDBMS 无法优化来自 PROCEDURE/FUNCTION 的子查询/结果集,也无法在其行上使用索引。
【讨论】:
以上是关于加入 2 个脚本 ORACLE 时的 SQL 性能的主要内容,如果未能解决你的问题,请参考以下文章
在同一 SQL.Server 上跨 2 个数据库加入时的 COLLATE 问题