天天看點

oracle分頁查詢資料重複問題

現在公司做的管理系統中有很多資料,往往需要分頁查詢,以前系統中出現了分頁資料重複的現象,起初以為是入的測試資料中有重複的,是以沒有深入分析,今天重新入了新的資料,進行分頁查詢,發現大多數的頁面都會存在與其他頁面的重複的資料,就開始排查,先從代碼上進行,沒有問題,構造的sql語句也沒有問題,将sql語句直接在oracle上運作傳回結果一比較,發現oracle傳回的分頁資料本身都是有重複資料的,這下算是找到原因了,那就分析解決吧,直接找阿度幫忙,果然找到了相關問題的部落格,自己也記錄下,避免今後再入坑。

在oracle分頁查詢中,我們采用類似以下所示的公認的比較高效的資料庫分頁查詢語句(Effective Oracle by Design中有描述、衆多oracle使用者也做過測試)。寫道 SELECT * FROM (  SELECT A.*, ROWNUM RN  FROM (SELECT * FROM TABLE_NAME) A WHERE ROWNUM <= n) WHERE RN > m  這裡的ROWNUM是一個僞列,它是oracle為查詢結果所編的一個号,第一行的ROWNUM為1,第二行為2,以此類推。 因為oracle是按塊進行讀取資料的,如果資料按順序存儲,則可能使讀取出來的資料是按順序的,給使用者誤解為預設排序。

事實上,oracle沒有進行任何排序操作,如果sql沒有要求排序,oracle會順序的從資料塊中讀取符合條件的資料傳回到用戶端。是以在沒有使用排序sql的時候,分頁傳回的資料可能是按順序的,也可能是雜亂無章的,這都取決與資料的存儲位置。在分頁查詢過程中,如果資料的實體位置發生了改變,就可能會引起分頁資料重複的現象。 是以,要正确使用分頁查詢,sql語句中必須有排序條件。

但是,在有排序條件的時候,仍然會出現資料重複的現象,這是為什麼呢? 

通過了解oracle的排序機理就會明白,出現這種情況的原因是因為排序列值的不唯一性。 Oracle這裡使用的排序算法不具有穩定性,也就是說,對于鍵值相等的資料,這種算法完成排序後,不保證這些鍵值相等的資料保持排序前的順序。解決的方法是在後邊增加一個唯一性列,比如主鍵。

是以解決方法如下(兩個條件必須同時滿足): 

  1.sql語句中需要有排序條件。 

  2.排序條件如果沒有唯一性,那麼必須在後邊跟上一個唯一性的條件,比如主鍵。

上一篇: oracle的分頁