选择需要很长时间才能返回的计数

时间:2018-08-17 15:45:41

标签: sql oracle oracle11g

我正在执行一个复杂的查询,该查询将在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是否正常?还是为什么会这样? 我该如何避免这个问题?

3 个答案:

答案 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
)