楼主: Kevin__Zhang

[精华] 你是否仍迷信rowid分页?

[复制链接]
论坛徽章:
6
ITPUB季度 技术新星
日期:2011-08-31 15:27:58ITPUB十周年纪念徽章
日期:2011-11-01 16:26:292012新春纪念徽章
日期:2012-01-04 11:57:36咸鸭蛋
日期:2012-03-05 13:10:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:16:00优秀写手
日期:2013-12-18 09:29:09
11#
 楼主| 发表于 2012-4-19 14:32 | 只看该作者
哈哈,精了。 谢谢斑竹,最近正好肾虚,混个精补补

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
12#
发表于 2012-4-19 14:46 | 只看该作者
肾虚??你一夜八次郎啊

使用道具 举报

回复
论坛徽章:
27
ITPUB官方微博粉丝徽章
日期:2011-08-17 10:35:36托尼托尼·乔巴
日期:2017-10-25 16:45:57秀才
日期:2017-04-05 13:18:06秀才
日期:2017-03-02 10:35:322016猴年福章
日期:2016-02-23 09:58:342016猴年福章
日期:2016-02-18 09:31:302015年新春福章
日期:2015-03-06 11:57:312014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:07:31
13#
发表于 2012-4-19 14:59 | 只看该作者
真不错~我一直怀疑rowid分页效率高不太靠谱,又不知道怎么去证明

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
14#
发表于 2012-4-19 22:09 | 只看该作者
很有意思的发现!如果这页的ROWID分散在很多块中,又会回到10G的那种结果?
用ROWID的方法,建议最后加ORDER BY对输出排序。

使用道具 举报

回复
论坛徽章:
10000
绿钻
日期:2016-02-22 15:43:08绿钻
日期:2016-03-01 18:19:01绿钻
日期:2016-02-22 15:43:08绿钻
日期:2016-03-01 18:19:01绿钻
日期:2015-12-16 18:42:35绿钻
日期:2015-12-11 00:18:01绿钻
日期:2015-09-10 13:05:08绿钻
日期:2015-12-11 00:18:01绿钻
日期:2015-09-10 13:05:08绿钻
日期:2015-09-10 13:05:08
15#
发表于 2012-4-19 22:54 | 只看该作者
good

使用道具 举报

回复
论坛徽章:
22
ITPUB十周年纪念徽章
日期:2011-11-01 16:21:152014年世界杯参赛球队: 比利时
日期:2014-06-15 20:40:142014年世界杯参赛球队: 科特迪瓦
日期:2014-06-30 19:29:262014年世界杯参赛球队:西班牙
日期:2014-07-08 21:49:56ITPUB元老
日期:2014-08-04 21:10:48优秀写手
日期:2014-09-24 06:00:13itpub13周年纪念徽章
日期:2014-10-03 10:51:25itpub13周年纪念徽章
日期:2014-10-08 15:16:50itpub13周年纪念徽章
日期:2014-10-08 15:16:50itpub13周年纪念徽章
日期:2014-10-08 15:16:50
16#
发表于 2012-4-19 23:07 | 只看该作者
学习下,^_^,实践出真理

使用道具 举报

回复
论坛徽章:
6
ITPUB季度 技术新星
日期:2011-08-31 15:27:58ITPUB十周年纪念徽章
日期:2011-11-01 16:26:292012新春纪念徽章
日期:2012-01-04 11:57:36咸鸭蛋
日期:2012-03-05 13:10:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:16:00优秀写手
日期:2013-12-18 09:29:09
17#
 楼主| 发表于 2012-4-20 07:50 | 只看该作者
newkid 发表于 2012-4-19 22:09
很有意思的发现!如果这页的ROWID分散在很多块中,又会回到10G的那种结果?
用ROWID的方法,建议最后加ORD ...

是,当11g的表的数据是彻底无序,也就是说集群因子最大化(和表的行数一样多),
这种情况下,11g的rowid分页性能是和10g的rowid分页性能一样的。也是每个rowid都需要产生一个块读。

使用道具 举报

回复
论坛徽章:
115
生肖徽章:狗
日期:2007-01-06 21:14:12马上有车
日期:2014-03-06 16:45:08马上加薪
日期:2014-05-09 12:27:582014年世界杯参赛球队: 英格兰
日期:2014-07-03 13:10:44青年奥林匹克运动会-竞技体操
日期:2014-09-10 15:30:57马上有钱
日期:2014-10-31 13:56:48美羊羊
日期:2015-03-04 14:48:582015年新春福章
日期:2015-03-06 11:57:31懒羊羊
日期:2015-04-23 19:26:10金牛座
日期:2015-09-17 08:21:44
18#
发表于 2012-4-20 09:17 | 只看该作者
本帖最后由 atgc 于 2012-4-20 10:03 编辑

consistent gets值大不, 并不等于就一定慢,如果排序分页需要提取所有字段,显然是ROWID分页快

SQL> select count(*) from t100;
  COUNT(*)
----------
    150000

set autot trace
set timi on

SQL> select /*+ all_rows */ *
     from   (select rownum rn,t.*
             from   (select  * from t100 order by id) t
             where  rownum<1000)
     where  rn >900;  
99 rows selected.
Elapsed: 00:00:00.39

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       4555  consistent gets
          0  physical reads
          0  redo size
      12772  bytes sent via SQL*Net to client
        404  bytes received via SQL*Net from client
          8  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         99  rows processed

SQL> select /*+ ordered use_nl(p s) */ *
     from   (select rownum rn,rd
             from   (select rowid rd from t100 order by id) t
             where  rownum<1000) p,
            t100 s
     where rn>900 and p.rd=s.rowid;
99 rows selected.
Elapsed: 00:00:00.10

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       4654  consistent gets
          0  physical reads
          0  redo size
      14303  bytes sent via SQL*Net to client
        404  bytes received via SQL*Net from client
          8  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         99  rows processed
         


使用道具 举报

回复
论坛徽章:
6
ITPUB季度 技术新星
日期:2011-08-31 15:27:58ITPUB十周年纪念徽章
日期:2011-11-01 16:26:292012新春纪念徽章
日期:2012-01-04 11:57:36咸鸭蛋
日期:2012-03-05 13:10:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:16:00优秀写手
日期:2013-12-18 09:29:09
19#
 楼主| 发表于 2012-4-20 09:50 | 只看该作者
atgc 发表于 2012-4-20 09:17
consistent gets值大不, 并不等于就一定慢,如果排序分页需要提取所有字段,显然是ROWID分页快

SQL> sel ...

此帖主要目的是揭露一个一直被忽略的11g新特性。11g得益于这个新特性,rowid分页基本普遍优于rownum分页。

而在10g中由于没有这个特性,那么要考虑的就很多了。
页后翻的页数,以及页的大小,以及行的长度,以及集群因子,都可能决定了rownum和rowid谁的性能更好。

所以也可以通过调整:页数,页大小,行长度,集群因子 这些参数,来构造不同的实验得到不同结果。

譬如:
select /*+ ordered use_nl(p s) */ *
      from (
            select rownum rn,rd
            from (select  rowid rd from test order by created)
            t where rownum<8000) p,
            test s
      where rn>7000 and p.rd=s.rowid; swp1 >swp1 >  2    3    4    5    6    7
999 rows selected.
Elapsed: 00:00:00.03
Execution Plan
----------------------------------------------------------
Plan hash value: 827357089
-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |  7999 |   437K|  8321   (1)| 00:01:57 |
|   1 |  NESTED LOOPS               |           |  7999 |   437K|  8321   (1)| 00:01:57 |
|*  2 |   VIEW                      |           |  7999 |   195K|   316   (1)| 00:00:05 |
|*  3 |    COUNT STOPKEY            |           |       |       |            |          |
|   4 |     VIEW                    |           |   182K|  2138K|   316   (1)| 00:00:05 |
|   5 |      INDEX FULL SCAN        | TEST_IND1 |   182K|  3385K|   316   (1)| 00:00:05 |
|   6 |   TABLE ACCESS BY USER ROWID| TEST      |     1 |    31 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("RN">7000)
   3 - filter(ROWNUM<8000)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1081  consistent gets
          0  physical reads
          0  redo size
      49093  bytes sent via SQL*Net to client
       1218  bytes received via SQL*Net from client
         68  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        999  rows processed



swp1 >select *
       from (
             select rownum rn,t.*
             from
             (select  id,status,type,created from test2 order by created) t
             where rownum<8000)
       where rn >7000;    2    3    4    5    6    7
999 rows selected.
Elapsed: 00:00:00.01
Execution Plan
----------------------------------------------------------
Plan hash value: 1795700156
---------------------------------------------------------------------------------------------
| Id  | Operation                      | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |            |  7999 |   398K|    30   (0)| 00:00:01 |
|*  1 |  VIEW                          |            |  7999 |   398K|    30   (0)| 00:00:01 |
|*  2 |   COUNT STOPKEY                |            |       |       |            |          |
|   3 |    VIEW                        |            |  7999 |   296K|    30   (0)| 00:00:01 |
|   4 |     TABLE ACCESS BY INDEX ROWID| TEST2      |   182K|  4455K|    30   (0)| 00:00:01 |
|   5 |      INDEX FULL SCAN           | TEST2_IND1 |  7999 |       |    12   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("RN">7000)
   2 - filter(ROWNUM<8000)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        163  consistent gets
          0  physical reads
          0  redo size
      31838  bytes sent via SQL*Net to client
       1218  bytes received via SQL*Net from client
         68  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        999  rows processed


可以看到我构造的这个结果:
         rowid     rownum
时间:  00.03    00.01   
块读:   1081    163  



此外,更重要的一点就是,关于你的看执行时间不看 块读 的做法我不认同。
一是因为在我们的实验中全部都是逻辑读。
而要知道,在真正的环境中,这种全表的块读是很容易产生物理读的,而常常多一个物理读的开销就能抵得上千百个逻辑读。

二是因为大部分的系统瓶颈都在IO



使用道具 举报

回复
论坛徽章:
115
生肖徽章:狗
日期:2007-01-06 21:14:12马上有车
日期:2014-03-06 16:45:08马上加薪
日期:2014-05-09 12:27:582014年世界杯参赛球队: 英格兰
日期:2014-07-03 13:10:44青年奥林匹克运动会-竞技体操
日期:2014-09-10 15:30:57马上有钱
日期:2014-10-31 13:56:48美羊羊
日期:2015-03-04 14:48:582015年新春福章
日期:2015-03-06 11:57:31懒羊羊
日期:2015-04-23 19:26:10金牛座
日期:2015-09-17 08:21:44
20#
发表于 2012-4-20 10:11 | 只看该作者
Kevin__Zhang 发表于 2012-4-20 09:50
此帖主要目的是揭露一个一直被忽略的11g新特性。11g得益于这个新特性,rowid分页基本普遍优于rownum分页。 ...

集群因子,不可能每个字段的集群因子都很小。如果一个字段的集群因子小了,别的字段的集群因子就会变大

说明一下,我这里是全表扫描,真实业务中,未必能做到都利用索引
即使物理读也是ROWID分页快,执行速度是客户体验,也是我们需要的效果

SQL> set autot trace
SQL> alter system  flush buffer_cache;

System altered.

SQL> select /*+ all_rows */ *
  2       from   (select rownum rn,t.*
  3               from   (select  * from t100 order by id) t
  4               where  rownum<1000)
  5       where  rn >900;

99 rows selected.

Elapsed: 00:00:00.59

Statistics
----------------------------------------------------------
          4  recursive calls
          0  db block gets
       4733  consistent gets
       4548  physical reads          0  redo size
      12772  bytes sent via SQL*Net to client
        404  bytes received via SQL*Net from client
          8  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         99  rows processed

SQL> alter system  flush buffer_cache;

System altered.

SQL> select /*+ ordered use_nl(p s) */ *
          from (
                select rownum rn,rd
                from (select  rowid rd from t100 order by id)
                t where rownum<1000) p,
                t100 s
          where rn>900 and p.rd=s.rowid;

99 rows selected.

Elapsed: 00:00:00.21

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       4654  consistent gets
       4548  physical reads          0  redo size
      14303  bytes sent via SQL*Net to client
        404  bytes received via SQL*Net from client
          8  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         99  rows processed

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表