rowid高速分页解析

Oracle分页与ROWID详解
--分页第一步 获取数据物理地址
select t.rowid rid, t.lastdate from t_test t order by t.lastdate desc;

--分页第二步 取得最大页数
select rownum rn, rid
  from (select t.rowid rid, t.lastdate
          from t_test t
         order by t.lastdate desc)
 where rownum <= 10;
 
 --分页第三步 取得最小页数
 select rn,rid
   from (select rownum rn, rid
           from (select t.rowid rid, t.lastdate from t_test t order by t.lastdate desc)
          where rownum <= 10)
  where rn > 5;
  
  --分页第四步 再根据物理地址,查询出具体数据
  select t1.*,t1.rowid
    from t_test t1
   where t1.rowid in
         (select rid
            from (select rownum rn, rid
                    from (select rowid rid, t.lastdate from t_test t order by t.lastdate desc)
                   where rownum <= 10000)
           where rn > 5000);

 

        在8i以前rowid由file#+block#+row# 组成,占用6个bytes的空间,10 bit的file# ,22 bit 的block#,16 bit 的row#。

其中oracle的dba(data block address)是32 bits的,包括10 bit 的 file# 和 22 bit 的block#。

由于不存在0编号文件,oracle中的文件最大数量2^10-1=1023

而datafile能达到的最大size就是2^22*db_block_size

如果db_block_size为4k的datafile max size就是16G

如果db_block_size为8k的datafile max size就是32G

        从oracle 8开始rowid变成了extend rowid,由data_object_id#+rfile#+block#+row#组成,占用10个bytes的空间,

32bit的 data_object_id#,10 bit 的 rfile#,22bit 的 block#,16 bit 的 row#.由于rowid的组成从file#变成了rfile#,

所以数据文件数的限制也从整个库不能超过1023个变成了每个data_object_id不能超过1023个数据文件。当然,你或许要问,

为什么oracle不调整rowid中表示 file# 的 bit数量,这个应该是由于兼容性的引起的,在 oracle7 的索引中存储的rowid

就是 file# + block# + row# ,因为这样处理后关于索引的存储,oracle8和oracle7没有发生变化。

        虽然oracle使用了extend rowid,但是在普通索引里面依然存储了bytes的rowid,只有在global index中存储的是10bytes

的extend rowid,而extend rowid也是global index出现的一个必要条件。

 

1. rowid基本概念:
 1) rowid是一个伪列,是用来确保表中行的唯一性,它并不能指示出行的物理位置,但可以用来定位行

 2) rowid是存储在索引中的一组既定的值(当行确定后)。我们可以像表中普通的列一样将它选出来

 3) 利用rowid是访问表中一行的最快方式

 4) rowid需要10个字节来存储,显示为18位的字符串。

 


2. 什么情况下rowid会发生变化
一般来说,当表中的行确定后,rowid就不会发生变化。 但当如下情况发生时,rowid将发生改变:


1) 对一个表做表空间的移动后 


2) 对一个表进行了EXP/IMP后

在数据库中,`ROWID` 是一种伪列,它为表中的每一行返回一个唯一标识符。在实现分页查询时,可以利用 `ROWID` 来提高查询效率,特别是在数据量较大的情况下。以下是使用 `ROWID` 实现分页查询的一种常见方式: ### 查询语句结构 通过结合 `ROWID` 和子查询,可以实现分页效果。例如,在 Oracle 数据库中,可以使用如下 SQL 语句: ```sql SELECT * FROM ( SELECT a.*, ROWNUM rnum FROM ( SELECT * FROM your_table ORDER BY some_column ) a WHERE ROWNUM <= :upper_bound ) WHERE rnum >= :lower_bound; ``` - `:upper_bound` 表示当前页的最大行数(例如第一页的上限为 10)。 - `:lower_bound` 表示当前页的起始行数(例如第一页的下限为 1)。 - `ROWNUM` 是 Oracle 中的伪列,用于标识查询结果的行号。 ### 优化查询性能 为了进一步优化分页查询的性能,可以通过 `ROWID` 直接定位数据行。例如: ```sql SELECT * FROM your_table WHERE ROWID IN ( SELECT rid FROM ( SELECT rid, ROWNUM rnum FROM ( SELECT ROWID rid FROM your_table ORDER BY some_column ) WHERE ROWNUM <= :upper_bound ) WHERE rnum >= :lower_bound ) ORDER BY some_column; ``` 这种查询方式通过先获取 `ROWID`,再根据 `ROWID` 查询具体数据,避免了对整个表的重复扫描,从而提升性能。 ### 注意事项 1. `ROWID` 的值可能会因为数据的更新、删除或重组而发生变化,因此不适合用作长期存储的行标识。 2. 如果表中存在频繁的更新或删除操作,建议结合其他唯一标识列(如主键)来确保分页结果的准确性。 ### 优化建议 在实际应用中,如果分页查询涉及大数据量或复杂条件,建议结合索引进行优化。例如,在排序字段上创建索引以加快查询速度: ```sql CREATE INDEX idx_your_table_column ON your_table(some_column); ``` 通过索引和 `ROWID` 的结合使用,可以显著提升分页查询的效率[^1]。 ---
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值