【Oracle】-【ROWNUM与索引】-索引对ROWNUM检索的影响
2013-08-02 12:03
369 查看
看到ASK TOM的一篇文章,挺有感触的。
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:32812348052
主要问的是ROWNUM的问题。后面的一个讨论提问谈到:
select ename, sal
from emp
where rownum<=10
order by sal desc;
和
select ename, sal
from ( select ename, sal
from emp
order by sal desc)
where rownum<=10;
是否相同?
第一个SQL是先找到ROWNUM<10的记录,然后排序。
第二个SQL是先ORDER BY排序,再找ROWNUM<10的记录。
因此两种查询得到的答案不同,当然有时也会碰巧相同。
另外,如果表有索引,那么对于第二个SQL,可以从后面的记录开始读,避免排序。对于这个问题我做了实验:
create table t as select * from dba_objects;
create table t2 as select * from dba_objects;
create index t2_i on t2(object_id);
SQL> select * from (select owner, object_name, object_id from t order by object_id desc) where rownum<10;
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3299198703
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 864 | | 1189 (1)| 00:00:15 |
|* 1 | COUNT STOPKEY | | | | | | |
| 2 | VIEW | | 47308 | 4435K| | 1189 (1)| 00:00:15 |
|* 3 | SORT ORDER BY STOPKEY| | 47308 | 4435K| 9M| 1189 (1)| 00:00:15 |
| 4 | TABLE ACCESS FULL | T | 47308 | 4435K| | 150 (1)| 00:00:02 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<10)
3 - filter(ROWNUM<10)
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
7 recursive calls
0 db block gets
793 consistent gets
0 physical reads
0 redo size
878 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
9 rows processed
SQL> select * from ( select owner, object_name, object_id from t2 order by object_id desc) where rownum < 10;
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 98068844
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 864 | | 1164 (1)| 00:00:14 |
|* 1 | COUNT STOPKEY | | | | | | |
| 2 | VIEW | | 46110 | 4322K| | 1164 (1)| 00
:00:14 |
|* 3 | SORT ORDER BY STOPKEY| | 46110 | 4322K| 9848K| 1164 (1)| 00:00:14 |
| 4 | TABLE ACCESS FULL | T2 | 46110 | 4322K| | 150 (1)| 00:00:02 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<10)
3 - filter(ROWNUM<10)
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
7 recursive calls
0 db block gets
791 consistent gets
0 physical reads
0 redo size
878 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
9 rows processed
第二个SQL仅比第一个SQL少2个consistent gets,不像讨论中说的会明显的变化。这个讨论是2001年的,不知道是不是版本的问题?我用的是10g。
还请高手指点!
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:32812348052
主要问的是ROWNUM的问题。后面的一个讨论提问谈到:
select ename, sal
from emp
where rownum<=10
order by sal desc;
和
select ename, sal
from ( select ename, sal
from emp
order by sal desc)
where rownum<=10;
是否相同?
第一个SQL是先找到ROWNUM<10的记录,然后排序。
第二个SQL是先ORDER BY排序,再找ROWNUM<10的记录。
因此两种查询得到的答案不同,当然有时也会碰巧相同。
另外,如果表有索引,那么对于第二个SQL,可以从后面的记录开始读,避免排序。对于这个问题我做了实验:
create table t as select * from dba_objects;
create table t2 as select * from dba_objects;
create index t2_i on t2(object_id);
SQL> select * from (select owner, object_name, object_id from t order by object_id desc) where rownum<10;
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3299198703
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 864 | | 1189 (1)| 00:00:15 |
|* 1 | COUNT STOPKEY | | | | | | |
| 2 | VIEW | | 47308 | 4435K| | 1189 (1)| 00:00:15 |
|* 3 | SORT ORDER BY STOPKEY| | 47308 | 4435K| 9M| 1189 (1)| 00:00:15 |
| 4 | TABLE ACCESS FULL | T | 47308 | 4435K| | 150 (1)| 00:00:02 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<10)
3 - filter(ROWNUM<10)
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
7 recursive calls
0 db block gets
793 consistent gets
0 physical reads
0 redo size
878 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
9 rows processed
SQL> select * from ( select owner, object_name, object_id from t2 order by object_id desc) where rownum < 10;
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 98068844
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 864 | | 1164 (1)| 00:00:14 |
|* 1 | COUNT STOPKEY | | | | | | |
| 2 | VIEW | | 46110 | 4322K| | 1164 (1)| 00
:00:14 |
|* 3 | SORT ORDER BY STOPKEY| | 46110 | 4322K| 9848K| 1164 (1)| 00:00:14 |
| 4 | TABLE ACCESS FULL | T2 | 46110 | 4322K| | 150 (1)| 00:00:02 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<10)
3 - filter(ROWNUM<10)
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
7 recursive calls
0 db block gets
791 consistent gets
0 physical reads
0 redo size
878 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
9 rows processed
第二个SQL仅比第一个SQL少2个consistent gets,不像讨论中说的会明显的变化。这个讨论是2001年的,不知道是不是版本的问题?我用的是10g。
还请高手指点!
相关文章推荐
- 【Oracle】-【ROWNUM与索引】-索引对ROWNUM检索的影响
- Oracle sql 调优:使用虚拟索引在生产环境测试创建索引对数据库性能的影响
- oracle中 rownum 对排序的影响
- Oracle中: distinct会影响rownum
- Oracle技术之索引与Null值对于Hints及执行计划的影响
- 数据库 day60,61 Oracle入门,单行函数,多表查询,子查询,事物处理,约束,rownum分页,视图,序列,索引
- Oracle rownum影响运行计划
- 【Oracle】-【COMMIT对索引的影响】-从trace看COMMIT对索引的影响
- oracle单表数据量的大小对索引性能的影响
- Oracle sql 调优:使用虚拟索引在生产环境测试创建索引对数据库性能的影响
- 有关Oracle表分区进行(DML)维护后对索引的影响的分析
- Oracle全文检索建索引,存储过程,以及java方法调用高亮显示
- 【oracle】truncate 操作对索引的影响
- oracle 索引 。其中全文检索最变态
- Oracle模糊查询之(5.1认识全文索引之什么是分词[lexer])oracle Text 全文检索功能对中文分词的支持情况
- 只需在order by 的字段上加主键或索引即可让oracle先按该字段排序,然后再用rownum标号
- Oracle 基础篇 --- 重建B树索引对性能的影响
- Oracle之如何在线创建索引,并且不影响update
- 有关Oracle表分区进行(DML)维护后对索引的影响的分析
- 【Oracle】-【COMMIT对索引的影响】-从trace看COMMIT对索引的影响