我正在执行一个复杂的查询,该查询将在3秒内完成:
WITH
Query1 as
( select ...
),
Query2 as
( select ... from Query1 ...
),
ComplexQuery AS
( select ... from Query2 ...
)
select * from ComplexQuery;
在这些查询中,有很多操作,例如GROUP BY, ORDER BY, UNION
。
但是当我用此更改最后一行时:
select count (*) from ComplexQuery;
这会产生奇怪的效果。查询开始执行了很长时间。我等了大约30分钟,然后停了下来。
我希望,由于原始查询在3秒钟内执行,因此计数大约需要0.01秒,因此总时间为3.01秒。 相反,我看到的是该计数似乎开始了涉及所有先前子查询的某种递归-这是我可以想象的。
Oracle/SQL
是否正常?还是为什么会这样?
我该如何避免这个问题?
答案 0 :(得分:1)
您可以尝试通过/*+MATERIALIZE*/
提示优化器实现中间步骤:
WITH Query1 as ( select /*+MATERIALIZE*/ ...)
,Query2 as ( select /*+MATERIALIZE*/ ... from Query1 ...)
,ComplexQuery AS ( select /*+MATERIALIZE*/ ... from Query2 ...)
select count (*) from ComplexQuery;
答案 1 :(得分:0)
这是有根据的猜测。
您的查询在外部查询中没有order by
或窗口函数。这意味着当开始生成结果时,可以将其返回。也就是说,您看到的是返回的 first 行,而不是 last 行。
执行select count(*)
时,需要生成复杂查询的整个结果集-然后进行计数。因此,在处理完所有结果之前,该查询无法返回任何结果。
我将此行为与嵌套循环联接相关联(尽管这不是唯一的一次发生)。如果发生这种情况,您将无法浏览返回的结果集。
答案 2 :(得分:0)
听起来听起来很傻,但是请尝试一下。
希望对您有帮助!
WITH
Query1 as
( select ...
),
Query2 as
( select ... from Query1 ...
),
ComplexQuery AS
( select ... from Query2 ...
),
CountRowsQuery AS
( select count (*) as RowsInQuery from ComplexQuery
)