嵌套视图的执行顺序

时间:2019-07-09 13:51:58

标签: oracle

根据我编写的示例,哪个将首先执行?它将从QueryView1中的Table1中选择所有记录并在QeryView2中进行过滤,还是仅从QueryView2中的where子句中获取QueryView1中的记录?

create or replace view QueryView2 as
Select column1
       ...
       columnx
  from SomeIrrelevantView a
  left join QueryView1 b
    on a.Id= b.Id
 where [conditions];

Create or replace view QueryView1 as
select column1
       ...
       columny
 from Table1;

1 个答案:

答案 0 :(得分:3)

  

它将从QueryView1中的Table1中选择所有记录并在QeryView2中进行过滤,还是仅从QueryView2中的where子句中获得QueryView1中的记录?

答案是“要么”。 Oracle将从Table1中的QueryView1中选择所有记录,如果优化器认为对您提交的针对QueryView2的任何查询,这将是最有效的。同样,如果优化程序认为 将是最有效的,则Oracle将首先评估SomeIrrelevantView,然后唯一访问Table1以获取所需的特定ID。

Oracle将使用所有可用信息来优化每个唯一查询,以制定最有效的计划。

例如,

SELECT * FROM QueryView2

Oracle的优化器将考虑SomeIrrelevantView中涉及的表(这些表的统计信息以及它们之间的联接),以估计从中得出多少行。如果该估算值很高,相对于Table1中的行数(“高”可能只是Table1中的行数的10%),Oracle可能会认为这样做的速度更快{{1}中的FULL SCAN

如果您的下一个查询是,

Table1

Oracle将再次应用其优化逻辑。这次,可以估计,在这种附加条件下,SELECT * FROM QueryView2 WHERE some_column BETWEEN 123 AND 456 将仅输出几行,因此得出结论,它应该使用SomeIrrelevantView上的索引访问访问Table1,以获取少数几行它需要的行。

如果之后的查询是

ID

...,并且您选择的所有列都不在SELECT irrelevant_view_column_a, irrelevant_view_column_b FROM QueryView2 中(Table1的定义中的“ [conditions]”均不引用QueryView2),并且{ {1}}是它的主键,Oracle可能会得出结论,它根本不需要访问Table1

底线:Oracle会尽其所能全面优化每个查询。您显然担心它会首先处理所有较低级别的视图,因此您不必担心太多。