内部表上的表扫描

时间:2013-10-15 19:15:18

标签: oracle

假设我有2张桌子 - TABLE-1&表-2和每个表有100万行,10列,索引在col1 ..

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

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?

2 个答案:

答案 0 :(得分:1)

是的,是的。

Oracle将有效地将此内联视图视为表格。它可以使用predicate pushing将内联视图中的过滤器应用于基表,并可能使用索引。解释计划将显示这一点。

表格,索引,示例数据和统计信息

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之前发生,并且使用了两个索引。默认情况下,一切都应该是可以预期的。

备注

这种类型的查询结构称为内联视图。虽然没有构建物理表,但短语“内部表”是一种思考查询在逻辑上如何工作的好方法。理想情况下,内联视图的工作方式与具有相同数据的预构建表完全相同。实际上有some cases事情不会以这种方式退出工作。但总的来说,你肯定是在正确的道路上 - 通过组合小型内联视图构建一个大型查询,并假设Oracle将正确地优化它。

答案 1 :(得分:0)

对于你的特定查询,不会使用任何索引,但我想你做了一些过滤,即where x.col1 = ###,我不确定oracle是否能够使用table-1 / table-2索引来过滤器,所以我建议你把where语句放在“union query”

里面