关于视图中使用rownum对执行计划的影响

最近发现在视图中使用rownum伪列会使执行改变,可能导致无法正常使用索引,以后要注意rownum的使用了,呵呵

 

现象如下:

SQL> create table test as
2 select * from dba_objects;

Table created.

SQL> create index ix_test_object_name on test(object_name);

Index created.

SQL> set autotrace on
SQL> select * from test t
2 where t.object_name='EMP';

Execution Plan
----------------------------------------------------------
Plan hash value: 3243212241

---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 177 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 177 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IX_TEST_OBJECT_NAME | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------

可以正常使用索引

SQL> create view v_test
2 as
3 select rownum as rid,
4 t.object_id,
5 t.object_name
6 from test t;

View created.

SQL> select * from v_test t
2 where t.object_name='EMP';

Execution Plan
----------------------------------------------------------
Plan hash value: 3564173094

------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 44356 | 3985K| 156 (1)| 00:00:02 |
|* 1 | VIEW | V_TEST | 44356 | 3985K| 156 (1)| 00:00:02 |
| 2 | COUNT | | | | | |
| 3 | TABLE ACCESS FULL| TEST | 44356 | 3421K| 156 (1)| 00:00:02 |
------------------------------------------------------------------------------

全表扫描了

但如果不用rownum

SQL> create view v_test1
2 as
3 select 1 as rid,
4 t.object_id,
5 t.object_name
6 from test t;

View created.

SQL> select * from v_test1 t
2 where t.object_name='EMP';

Execution Plan
----------------------------------------------------------
Plan hash value: 3243212241

---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 79 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 79 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IX_TEST_OBJECT_NAME | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------

这样就可以正常使用索引了,呵呵,至于为什么会这样,请读者自己考虑吧。

posted @ 2011-11-04 11:35  wwh  阅读(527)  评论(4编辑  收藏  举报