我怎样才能在 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走捷径
我有一个 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走捷径