ORACLE之 rowid 分頁

--普通寫法(顯示1-5頁) 

select empno, ename, job, hiredate, sal
from (select empno, ename, job, hiredate, sal, rownum rn 
          from (select empno, ename, job, hiredate, sal
                  from scott.emp tab 
                 --where empno != 0 order by tab.hiredate desc
                 ) emp 
         WHERE rownum <= 5) 
WHERE rn >= 1;

--rowid寫法
select /*+ordered use_nl(empT,empTab)*/ 
       empTab.empno, 
       empTab.ename, 
       empTab.job, 
       empTab.hiredate 
from (select rid 
          from (select remp.rid, rownum rn 
                  from (select /*+ index(tab,index_empno) */ 
                          rowid rid 
                          from scott.emp tab 
                          --where empno != 0 order by tab.hiredate desc
                         ) remp 
                 where rownum <= 5) 
         where rn >=1) empT, 
       scott.emp empTab 
where empT.rid = empTab.rowid;

性能比較:
---查詢第一頁普通寫法要比rowid寫法要快

---隨着翻頁次數的增多,普通寫法需要回表的記錄越來越多,性能下降很快。比如你要看200-250條的記錄,這時候普通寫法需要回表250條記錄,而rowid寫法只要回表200-250區間中的這50條記錄。

rowid 寫法優化的情況:
--第一層必須都在索引中掃描,不回表
--第二三層找到滿足條件的rowid
--最後根據rowid去回表找到記錄

總結:

關鍵就是oracle 的 rowid 屬性可以以最快速度的尋找到該行的數據,並且固定,不需要回表操作。

1、rowid是一個僞列,是用來確保表中行的唯一性,它並不能指示出行的物理位置,但可以用來定位行。 
2、rowid是存儲在索引中的一組既定的值(當行確定後)。我們可以像表中普通的列一樣將它選出來。
3、利用rowid是訪問表中一行的最快方式。 
4、rowid需要10個字節來存儲,顯示爲18位的字符串。 
rowid的組成結構爲: 
data object number(6位字符串)+relative file number(3位字符串)+block number(6位字符串)+row number(3位字符串),如:AAAADeAABAAAAZSAAA
5、我們可以藉助oracle提供的包dbms_rowid,來對rowid進行解析從而獲取關於行的相關信息: 
SQL>select
2 rowid,
3 dbms_rowid.rowid_object(rowid) obj_id,
4 dbms_rowid.rowid_relative_fno(rowid) df#,
5 dbms_rowid.rowid_block_number(rowid) blknum,
6 dbms_rowid.rowid_row_number(rowid) rowno
7 from p_test where rownum<5;
ROWID OBJ_ID DF# BLKNUM ROWNO
------------------ ---------- ---------- ---------- ----------
AAAQ+tAANAAAC6SAAA 69549 13 11922 0 AAAQ+tAANAAAC6SAAB 69549 13 11922 1 AAAQ+tAANAAAC6SAAC 69549 13 11922 2 AAAQ+tAANAAAC6SAAD 69549 13 11922 3
我們可以看到,通過rowid_row_number得到的行號是從0開始的,這是和rownum僞列的一個不同之處。我猜測rowid_row_number在求行號的時候是計算首行的偏移量。

一般來說,當表中的行確定後,rowid就不會發生變化。
但當如下情況發生時,rowid將發生改變:
1、對一個表做表空間的移動後
2、對一個表進行了EXP/IMP後
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章