专栏首页bisal的个人杂货铺【Oracle】-【ROWNUM与索引】-索引对ROWNUM检索的影响

【Oracle】-【ROWNUM与索引】-索引对ROWNUM检索的影响

看到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。

还请高手指点!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • dbms_xplan.display_awr方式获取执行计划的实验和之前的误导

    《查看Oracle执行计划的几种常用方法-系列1》(http://blog.csdn.net/bisal/article/details/38919181)这篇...

    bisal
  • 几种去重的SQL写法

    墨天轮社区的每日一题(https://www.modb.pro/test),可以说是个小而精的专栏,利用碎片时间,就可以学习知识,非常推荐。

    bisal
  • 一张几亿的分区表,能改名么?

    一个微信群中有位朋友问“一张几亿的分区表,能改名么?”。我想他要表达的,不是语法上是否可以改名,而是改名是否有什么影响?

    bisal
  • dbms_xplan.display_awr方式获取执行计划的实验和之前的误导

    《查看Oracle执行计划的几种常用方法-系列1》(http://blog.csdn.net/bisal/article/details/38919181)这篇...

    bisal
  • oracle--事物特性、锁、

    eadela
  • select into 和 insert int select

    zucchiniy
  • <导图>Mysql常用查询语法

    普通查询 查看整个表 格式: select * from 表名; 示例: select * from students; 查询指定字段 格式 ...

    zhaoolee
  • 2019Java面试宝典数据库篇 -- MySQL

    SQL 语言不同于其他编程语言的最明显特征是处理代码的顺序。在大多数据库语言中,代码按编码顺序被处理。但在 SQL 语句中,第一个被处理的子句是 FROM,而不...

    浩Coding
  • SQL*Plus 执行脚本时传递参数(@script_name var1,var2)

          在使用sqlplus执行sql脚本时,经常碰到向脚本传递参数的情形。类似于shell脚本的参数传递,我们同样可以向sql脚本传递参数,其方法是脚本后...

    Leshami
  • Oracle配置和使用闪回

    环境:RHEL 6.4 + Oracle 11.2.0.4 目录: 一、闪回查询

    Alfred Zhao

扫码关注云+社区

领取腾讯云代金券