rownum淺談(一)


只要做web開發,幾乎沒有不需要分頁查詢的,在oracle中,rownum就是用來進行處理分頁的。

1.rownum是oracle對結果集返回的一個偽列,也就是說是先查詢完結果之后再加上的一個虛列,相當於對符合條件的結果的一個序列號。如果有結果的話,rownum偽列產生的序號是按

照數據被查詢出來的順序添加上去的, rownum總是從1開始,依次加1。

select rownum,u.* from t_user u

可以看到,rownum按序顯示了。我們需要查找前10條數據

select rownum,u.* from t_user u where rownum <= 10

數據正常查找出來,沒有問題。如果我們查詢結果中有排序呢,看看結果如何

select rownum,u.* from t_user u where rownum <= 10 order by u.c_id desc;

select rownum,u.* from t_user u order by u.c_id desc;

       (第一條語句執行結果)                     

       (第二條語句執行結果)

可以看到數據沒有問題,換成下面的語句

select rownum,u.* from t_user u where rownum <= 10 order by u.c_createdate desc;

select rownum,u.* from t_user u order by u.c_createdate desc;

             (第一條語句執行結果)                            

             (第二條語句執行結果)

可以看到,按照創建時間排序查詢前10條有問題了,但是看第二條執行結果,創建時間最近的應該是chenz.ccsd而不是第一條中的43573830。為什么會這樣呢?

這是因為ORACLE內部的查詢優化器和索引搞的鬼。

當一條語句交給查詢優化器處理時,會有兩種情況:

一種如果排序列上有索引的話,則借助索引去查詢數據,這樣讀取出來的數據是有序的,然后為排序后的數據從第一行到最后一行賦予rownum值;

另一種排序列上沒有沒有索引的話,則會先進行全表掃描依次讀取數據,然后為數據賦予rownum值,再進行排序,此時所選取的數據就不是進行排序的了。

上面語句中c_id是有索引的,而c_createdate是沒有建立索引的。

由於排序列上不一定要有索引,所以在使用rownum分頁時,需要多加一層查詢,以保證rownum的連續性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM