1

假设我有 2 个表 - TABLE-1 和 TABLE-2,每个表都有 100 万行,10 列和 col1 上的索引。

现在我在这 2 个表(1 + 1 = 200 万)行上构建一个内部表,

select * from 
(select col1, col2,....col10 from table-1
union all
select col1, col2,....col10 from table-2) x

问题,

how will the internal table will be treated in Oracle since its a internal table..
1. Will the internal table will be treated as a table with index on col1?
2. Will this be captured in the Explain plan?
4

2 回答 2

1

是的,是的。

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 会正确优化它。

于 2013-10-16T01:36:22.730 回答
0

对于您的特定查询,不会使用任何索引,但我想您会进行一些过滤,即where x.col1 = ###,我不确定 oracle 是否能够使用 table-1/table-2 索引进行过滤,所以我建议您将“联合查询”中的 where 语句

于 2013-10-15T19:21:00.560 回答