日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

07. 分页写法小结

發布時間:2025/7/14 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 07. 分页写法小结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
07. 分頁寫法小結 原文:07. 分頁寫法小結

分頁的實現方式有這幾種:
1. 在前臺程序中,將所有的記錄都讀到本地,前臺程序通過游標在數據集中上下移動,數據量大的話,性能很差,不推薦
2. 前臺程序請求某一頁數據時,到數據庫做一次查詢,返回符合條件的相應記錄,這也是目前常用的方法
3. 對方式2的改進,當請求某一頁時,同時將前后幾頁一并返回,用戶翻頁時就不需要反復請求數據庫了。


對于2,3的實現,隨著SQL Server版本的升級,常用的方法有三種:TOP,ROW_NUMBER,OFFSET/FETCH NEXT。
測試數據:

if OBJECT_ID('split_pages') is not null drop table split_pages GO create table split_pages ( ID int primary key, Name varchar(100) ) GO declare @i int set @i=1 while @i<=300 begin insert into split_pages select @i,'TEST' + CAST(@i as varchar(10)) set @i=@i+10 end GO select * from split_pages

一. TOP

SQL Server 2000時多用,另外,有人用過set rowcount來分頁,原理類似TOP,不過需要反復設置set rowcount,不方便,而且set rowcount中的行數不能參與select語句的執行計劃,只能起到控制行數的作用。
1. 哪種TOP寫法更高效
(1) 利用order by正反排序

select * from (select top 10 * from (select top 20 * from split_pages order by ID) a order by ID desc) b order by ID

公式為:

declare @page_no int declare @page_size intselect * from (select top @page_size * from (select top @page_size*@page_no * from split_pages order by ID) a order by ID desc) b order by ID

做完最里層select后,再對派生表查詢時,index就沒有效果了,而且越往后面要top更多的數據,這種寫法會更慢。

?

(2) 利用NOT IN或者NOT EXISTS

select top 10 * from split_pages where ID NOT IN (select top 10 ID from split_pages order by ID) order by ID

公式為:

declare @page_no int declare @page_size intselect top @page_size * from split_pages where ID NOT IN (select top @page_size*(@page_no-1) ID from split_pages order by ID) order by ID

通常在寫SQL語句時,用IN/EXISTS不一樣,如果邏輯不變的話, EXISTS的效率高。

不過,利用NOT IN分頁,和用NOT EXISTS效果基本一樣,因為都需要掃完全部數據。

?

(3) 利用ID大于MAX(ID)

select top 10 * from split_pages where ID > (select MAX(ID) from (select top 10 ID from split_pages order by ID) t) order by ID

公式為:

declare @page_no int declare @page_size intselect top @page_size * from split_pages where ID > (select MAX(ID) from (select top @page_size*(@page_no-1) ID from split_pages order by ID) t) order by ID

在使用TOP分頁時,這種用法效率最高。

?

2. SQL Server 2000與2005中TOP的區別
(1) SQL Server 2000時,top不支持變量,所以分頁時,這些語句都要改成動態SQL
如下:

declare @page_no int declare @page_size int declare @sql varchar(8000)set @page_no = 2 set @page_size = 10 set @sql = 'select top ' + str(@page_size) + '* from split_pages ' + ' where ID > (select MAX(ID) from (select top ' + str(@page_size*(@page_no-1))+ ' ID from split_pages order by ID) t) order by ID' exec(@sql)

?

(2) SQL Server 2005開始,top可以直接使用變量

如下:

declare @page_no int declare @page_size int set @page_no = 2 set @page_size = 10 select top (@page_size) * from split_pages where ID NOT IN (select top (@page_size*(@page_no-1)) ID from split_pages order by ID) order by ID

?

二. ROW_NUMBER
SQL Server 2005開始的新語法,和ORACLE,DB2中的row_number()類似。性能比用TOP有所提升。

在利用ROW_NUMBER分頁時,總頁數/行數的計算,可以有這幾種寫法。
(1) 單獨的SQL語句去獲得總行數

select COUNT(*) AS TotRows from split_pages GO declare @page_no int declare @page_size intset @page_no = 2 set @page_size = 10;with tmp AS ( select *, ROW_NUMBER() OVER(order by ID) num from split_pages ) select ID, Name from tmp where num BETWEEN (@page_size*(@page_no-1)+1) AND @page_size*@page_no order by num

?

(2) 在ROW_NUMBER的同時用COUNT計算總行數

declare @page_no int declare @page_size intset @page_no = 2 set @page_size = 10;WITH tmp AS ( select *, ROW_NUMBER() OVER(order by ID) num, COUNT(*) OVER() total from split_pages ) select ID, Name from tmp where num BETWEEN (@page_size*(@page_no-1)+1) AND @page_size*@page_no order by num

?

(3) 僅使用ROW_NUMBER計算總行數,IO最少

declare @page_no int declare @page_size intset @page_no = 2 set @page_size = 10;with tmp as ( select *, ROW_NUMBER() OVER(order by ID) num, ROW_NUMBER() OVER(order by ID desc) num_desc from split_pages ) select ID, Name, num_desc + num -1 as total from tmp where num BETWEEN (@page_size*(@page_no-1)+1) AND @page_size*@page_no order by num

?

三. OFFSET/FETCH NEXT
SQL Server 2012的新語法,類似MYSQL,POSTGRESQL中的LIIMIT/OFFSET,據稱性能比ROW_NUMBER又有了提升。

declare @page_no int declare @page_size intset @page_no = 3 set @page_size = 10SELECT *,COUNT(*) OVER() AS Total FROM split_pages ORDER BY ID OFFSET (@page -1) * @size ROWS FETCH NEXT @size ROWS ONLY;

?

四. 其他方法
(1) 臨時表
在SQL Server 2000時,利用臨時表生成rownum來分頁,不推薦。

select IDENTITY(int,1,1) as num,* into #t from split_pages select * from #t where num between 11 and 20

?

(2) sp_cursoropen
利用游標,性能較差,原理類似在程序中把數據全部加載到本地,然后通過游標移動來分頁。不作推薦。

?

posted on 2014-06-23 17:15 NET未來之路 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/lonelyxmas/p/3804410.html

總結

以上是生活随笔為你收集整理的07. 分页写法小结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。