我怎样才能在 Oracle 10g 的限制下更快地执行此查询?

How can I make this query perform faster within Oracle 10g limitations?

我有一个 Oracle 查询,它的性能非常糟糕,我可以就可能的原因提出一些建议 and/or 关于如何改进它的建议。我在下面详细说明了原始查询的简化版本以及我尝试过的内容。

原始查询

Select * From
(
SELECT * FROM table1
Union All
SELECT * FROM table2
Union All
SELECT * FROM table3
Union All
SELECT * FROM table4
) GroupedData
LEFT JOIN
(
SELECT * FROM RecursiveCte
) ON GroupedData.id = RecursiveCte.id

我已将查询简化为通用的“select 全部”语句,只是为了简化此问题。

关于一些查询的几点...

GroupedData 子查询实际上有 4 个以上的联合,每个联合所查看的数据量各不相同,但受日期过滤器 returned 数据的限制。此查询的总数据 return 通常是 1500 条记录,尽管正在处理的数据量可能是数十万条记录。如果我 运行 这个查询本身, return 那 1500 行需要不到一秒的时间。

RecursiveCte 子查询使用 CONNECT BY 功能,因为 Oracle 10g 没有递归 CTE(这会容易得多)。如果我 运行 这个查询本身,它也需要不到一秒钟。

当我尝试通过 LEFT JOIN 将两者连接在一起时出现问题。当我这样做时,对于相同的日期范围参数,查询 运行 需要 8 多分钟。

我已经尝试将它们设置为以下 CTE 格式,但它们的性能都更差!

方法一

WITH GroupedData AS
    (
    SELECT * FROM table1
    Union All
    SELECT * FROM table2
    Union All
    SELECT * FROM table3
    Union All
    SELECT * FROM table4
    ) GroupedData,

    RecursiveCte AS
    (
    SELECT * FROM RecursiveCte
    )

Select * From
    GroupedData
    LEFT JOIN RecursiveCte ON GroupedData.id = RecursiveCte.id

方法#2

WITH Query1 AS
    (SELECT * FROM table1),

    Query2 AS
    (SELECT * FROM table2),

    Query3 AS
    (SELECT * FROM table3),

    Query4 AS
    (SELECT * FROM table4),

    RecursiveCte AS
    (
    SELECT * FROM RecursiveCte
    )

Select * From
    (
    Select * From Query1
    Union All
    Select * From Query2
    Union All
    Select * From Query3
    Union All
    Select * From Query4
    ) GroupedData
    LEFT JOIN RecursiveCte ON GroupedData.id = RecursiveCte.id

除了 Oracle 10g 的限制之外,我也是 运行 具有只读权限的数据库用户,这限制了我在数据库中的操作。

非常感谢任何帮助,如果我没有提供足够的上下文,请提前道歉!

谢谢

当您有两个查询 运行 分别快,但一起 运行 慢时,最简单的解决方案通常是添加一个 ROWNUM,如下所示:

Select * From
(
  ...
  --Prevent optimizer transformations to improve performance:
  WHERE ROWNUM >= 1
) GroupedData
LEFT JOIN
(
  SELECT * FROM RecursiveCte
  --Prevent optimizer transformations to improve performance:
  WHERE ROWNUM >= 1
) ON GroupedData.id = RecursiveCte.id

请参阅我的回答 以更详细地解释此技巧为何有效。

虽然上述技巧通常是最简单 的解决方案,但它通常不是最好的 解决方案。甲骨文重写你的查询不好总是有原因的;可能缺少 table 统计信息,或者条件太复杂以至于 Oracle 无法估计返回的行数等。但是如果您现在不想花几个小时调查 SQL 监控报告,那么OK走捷径