是的,是的。
Oracle 将有效地将此内联视图视为一个表。它可以使用谓词推送将内联视图上的过滤器应用于基表,并可能使用索引。解释计划将显示这一点。
表、索引、样本数据和统计信息
create table table1(col1 number, col2 number, col3 number, col4 number);
create table table2(col1 number, col2 number, col3 number, col4 number);
create index table1_idx on table1(col1);
create index table2_idx on table2(col1);
insert into table1 select level, level, level, level
from dual connect by level <= 100000;
insert into table2 select level, level, level, level
from dual connect by level <= 100000;
commit;
begin
dbms_stats.gather_table_stats(user, 'TABLE1');
dbms_stats.gather_table_stats(user, 'TABLE2');
end;
/
解释显示谓词推送和索引访问的计划
explain plan for
select * from
(
select col1, col2, col3, col4 from table1
union all
select col1, col2, col3, col4 from table2
)
where col1 = 1;
select * from table(dbms_xplan.display);
Plan hash value: 400235428
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 40 | 2 (0)| 00:00:01 |
| 1 | VIEW | | 2 | 40 | 2 (0)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
| 3 | TABLE ACCESS BY INDEX ROWID BATCHED| TABLE1 | 1 | 20 | 2 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | TABLE1_IDX | 1 | | 1 (0)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID BATCHED| TABLE2 | 1 | 20 | 2 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | TABLE2_IDX | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("COL1"=1)
6 - access("COL1"=1)
注意谓词是如何在 , 之前发生的VIEW
,并且两个索引都被使用了。默认情况下,一切都应该像预期的那样正常工作。
笔记
这种类型的查询结构称为内联视图。尽管没有构建物理表,但“内部表”这个短语是思考查询逻辑如何工作的好方法。理想情况下,内联视图的工作方式与具有相同数据的预构建表完全相同。实际上,在某些情况下,事情并不会以这种方式停止工作。但总的来说,您肯定走在正确的道路上——通过组装小的内联视图来构建大型查询,并假设 Oracle 会正确优化它。