内联视图限制

内联视图限制

问题描述:

SELECT in_ev.type, pl.name, in_ev.year 
FROM places pl INNER JOIN (SELECT e.type, e.place_id, e.year 
          FROM events e)in_ev ON in_ev.place_id=pl.place_id 
WHERE EXISTS (SELECT 1 FROM in_ev sub_ev WHERE sub_ev.year=1994) 

我想了解如何处理内联视图,以及为什么我们不能将它们用作where子句子查询中的“源表”。当我尝试运行此查询时,我得到ORA-00942:表或视图不存在内联视图限制

上面的代码仅用于说明的原因。

普通表和内联视图之间存储和处理的确切区别是什么?

where子句中的子查询无法看到内嵌视图,我想你已经想通了;这是一个范围问题,真的。没有存储空间,以及它如何在内存中管理和处理有点落后于优化器 - 例如,它可能会大幅改写事物。我猜想,在评估内嵌视图之前,子查询可能会进行逻辑评估。

由于解析器在查询被实际执行之前抛出ORA-00942,因此如何处理内联视图是一个有争议的问题。

您可以使用,而不是子查询分解:

WITH in_ev AS (
    SELECT e.type, e.place_id, e.year 
    FROM events e 
) 
SELECT in_ev.type, pl.name, in_ev.year 
FROM places pl INNER JOIN in_ev ON in_ev.place_id=pl.place_id 
WHERE EXISTS (SELECT 1 FROM in_ev sub_ev WHERE sub_ev.year=1994) 

这看起来很奇怪这样一个人为的例子,但你acknowleged,它在这个问题说明。 where子句中的子查询可以看到CTE - 它在解析器的范围内。

正如@mathguy在评论中指出的那样,优化器可能仍然将CTE视为子查询,但这通常不是您需要担心的事情 - 特别是如果您只是想避免出现错误。

+1

要添加到Alex的解释中,并进一步回答有关评估和存储的问题:当Optimizer看到因式分解子查询(WITH子句中的“视图”)时,可以自由考虑两个选项并选择它认为的那个效率更高。一种是将它视为内联视图(在FROM和WHERE子句中就地评估它);或者,它可以将其视为临时全局表,只计算一次,保存并使用它,就像它可能使用存储的表一样,在查询的其余部分使用它。 CBO将选择哪个选项取决于几件事情。 – mathguy