根据我编写的示例,哪个将首先执行?它将从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;
答案 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会尽其所能全面优化每个查询。您显然担心它会首先处理所有较低级别的视图,因此您不必担心太多。