程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> Oracle數據庫查詢高效分頁

Oracle數據庫查詢高效分頁

編輯:Oracle數據庫基礎

由於網頁渲染速度的影響,在C/S程序中那種一個Grid包含幾千、上萬行的數據基本上在網頁是無法展現的,因此一般采用分頁的形式顯示(也可能采用Visual Srolling方式加載的,企業應用系統的不是很常見),ASP.Net 的數據控件一般帶有分頁功能,3.5以後還提供了單獨的分頁控件,也有用過ASPNetPager這個第三方的組件。

分頁的控件實在很方便,以前的處理方式就是數據都拿出來,然後由控件進行處理,一般數據量不大的時候應該說感覺不出來優劣,但由於每次從數據庫取的時候都是取所有的數據,肯定會增加數據庫的壓力,傳輸的數據庫多了對網絡帶寬也會產生壓力的。很有可能查出來1萬條數據,最後顯示只用到啟用50條,翻頁的時候又重新去查1萬條數據,顯示之後的的又50條。

以下的分頁SQL比較常見的,在SQL Server也有對應的使用TOP關鍵字的版本,記得剛學Oralce的時候就想著怎麼不能rownum between minValue and maxValue的用法。與最初的疑惑的原理一樣,rownum是在查詢過程中生成的,因此以下的SQL其實是查出來5300行,然後扔掉了前面5000行,返回後面的300行。當然這種已經進了一大步的,由數據庫返回的數據變少的,只是當查詢的頁數比較大的時候,查詢還是存在一定的浪費。

  1. select *
  2. from (select a.*, rownum as rnum
  3. from (select * from yz_bingrenyz) a
  4. where rownum <=5300)
  5. where rnum >= 5000

Linq提供了Skip和Take的API可以用於分頁,由於使用的是Entity Framework,在好奇的驅使下用EFProfiler查看生成的SQL,才知道這樣以下分頁更好。 主要就是使用了row_numer()over()這樣的分析函數,可以直接找到那第5000行開始的地方,然後在取出30行就行了。

  1. select *
  2. from (select *
  3. from (select t.*,
  4. row_number() OVER(ORDER BY null) AS "row_number"
  5. from yz_bingrenyz t) p
  6. where p."row_number" > 5000
  7. ) q
  8. where rownum <= 30

比較分析:

本機測試前者耗時1.3s,後者僅0.25s,從以下的執行計劃也能看出差異來。

L42E79ANC}UAF1O9XP%0MG8

image

實際應用

如果每次查詢都要寫這種SQL那肯定比較麻煩,可以采用存儲過程進行封裝,但由於要動態執行SQL,效率肯定又要打折扣,所以在ASP.NET中用C#封裝函數比較好,對於沒有使用實體框架的而用ADO.Net的,傳入表名 、主鍵名、頁數、要取的行數作為參數,用DBCommand進行執行返回結果即可。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved