資料分頁方法新思路,速度非常快!

來源:互聯網
上載者:User
分頁|資料|速度 這篇文章要達到的目的就是,實現大資料分頁瀏覽並最佳化速度。

建立一個web 應用,分頁瀏覽功能必不可少;這個問題也是長久以來最普遍的問題,目前也得到了較好的解決,其中象ASP 程式的分頁演算法有很多,比如使用ado 對象的PageSize 這些屬性,按記錄總數計算頁,然後跳轉記錄集再輸出;也有編寫預存程序實現分頁資料,這些方面各有優缺點,以下本人介紹一種應用實際項目中速度非常快的分頁演算法;

關鍵點:SQL (用TOP 和 自動編號 實現)
頁面指令碼 (瀏覽器回退功能)

環境:
IIS/SQL Server/Access
表結構:
create table 內容表 (
自動編號 IDENTITY(int, 1,1) not null,
分類編碼 <I>var</I>char(20) null,
標題 <I>var</I>char(255) NULL,
內容 <I>var</I>char(4000) null,
時間 datetime null,
)

實現原理:
這個表設定了自動編號欄位,這個欄位的特性就是產生不重複的整形,包括刪除了記錄後該欄位仍然保持‘流水性’(註:通常在系統資料表建設中,這種欄位的運用很少,因為編號不能自由管理,但在這裡使用它,主要是想在文章中省略編號維護的代碼)。

分頁:
那麼第一步,就是查詢一個頁的資料;如果有100筆記錄,按20記錄一頁,那麼通常的分頁演算法就是“頁總數=總記錄 除 分頁的控制數 [有餘數的話,頁總數加一]”,這樣的做法就導致必須產生所有記錄的一個大記錄集;從而,又有人提出了用預存程序的分頁演算法,前者是asp 指令碼產生大記錄集,這樣速度相當慢,後者是殺雞用牛刀,雖然我經常寫預存程序,但根據我的思路會發現寫預存程序完全多餘。

在SQL 中,許多剛接觸它的朋友都知道 Top 修飾關鍵字的作用;例如:select TOP 1 * from table1 --這樣就實現從Table1表返回只有一條記錄的記錄集那麼分頁最佳化的最終目的就是避免產生過大的記錄集,通過TOP 即可完全控制;現在查詢表應該是 select Top 20 自動編號,標題,內容,時間 from 內容表。

但現在還有個問題,就是如何定位,Top 不可能自動給我們定位輸出某個頁,這就設計到了where 從句,根據一個特定條件輸出正確的內容;注意:記錄的 order by 排序是非常重要的,這個決定了這個演算法的成敗;

這裡的示範是DESC 方式,倒序排列,比如網站的軟體更新,就是最近的更新放最前面,而這個就是倒序方式。

OK,下面來看看實際代碼,首先要確定是否為起始頁。


dim strSQL,i,endID,isBeginPage
const Cnt_PageSize = 20 '定義每頁記錄的大小
'通過檢查瀏覽器傳遞的Page 參數的值來判斷是否為進入下一頁的操作
isBeginPage = isEmpty(request("Page")) or request("Page")="" or request("Page")<>"next"
'這裡是分頁的核心
if isBeginPage then '如果是起始頁
'查詢=列出分類編碼等於參數flbm 的記錄,按倒序排列,並只列出前 Cnt_PageSize 筆 (Cnt_PageSize是常量定義,比如20)
strSQL = "select TOP " & Cnt_pageSize & " 自動編號,標題,內容,時間 from 內容表 where 分類編碼= '" & TRIM(SQLEncode(request("flbm"))) & "' order by 自動編號 desc"
else '如果不是起始頁
if request("Page")="next" then '這裡這樣寫是為了加強代碼的表現,如果參數為next ,則表示取下頁內容
'查詢=列出分類編碼等於參數flbm的記錄並且要小於自動編號endID (endID也是參數),並倒序排列,並只列出前 Cnt_PageSize 筆 (Cnt_PageSize是常量定義,比如20)
strSQL = "select TOP " & Cnt_pageSize & " 自動編號,標題,內容,時間 from 內容表 where 分類編碼= '" & TRIM(SQLEncode(request("flbm"))) & "' and 自動編號<" & request("endID") & " order by 自動編號 desc"
End if
end if

'開啟資料連線執行SQL 並建立記錄集
set rs = Cnn.Execute(strSQL)
if not rs.Eof then '這裡寫入判斷是否為Eof 可以不要,但是,在這裡卻有它的特殊意義
call TableTitle '這裡是自寫的函數,用於建立表格標記
call beginTr '這裡是建立表格tr標記

for i=0 to rs.fields.Count-1 '遍曆記錄集欄位
call AddCol(rs(i).name) '輸出欄位名
Next

call endTr

while not rs.eof '迴圈記錄集內容,並輸出
call beginTr

for i=0 to rs.fields.Count-1
call AddRow(ASPEncode(rs(i).value))
Next
call endTr
endID = rs("自動編號") '這裡儲存每次輸出的自動編號值
rs.MoveNext
Wend
call TableBottom '到此為止,就簡單的將記錄集內容全部輸出
'這裡輸出翻頁標記,vbaIIF 是自寫函數
原型為 <I>function</I> vbaIIF(a,b,c)
if a then
vbaIIF =b
else
vbaIIF =c
end if
end <I>function</I>

上一頁的實現是通過指令碼呼叫瀏覽器的功能 history.back(1) 實現,那麼回頁時並不需要在伺服器端重建資料,速度不用考慮了。
在首頁的時候,上一頁的連結應該是無效的,通過 vbaIIF(isBeginPage,"disabled","") 實現,如果為首頁,那麼在標記中加入 disabled 屬性 ,如果不是首頁,則加入history.back(1); 指令碼指令,用於回退瀏覽頁。
下一頁是傳遞Page 參數和endID參數,Page 設定為 next 表示為下一頁的動作,endID 表示目前記錄集的末尾編號,下頁將由此分頁。

response.Write("〈a href=""#"" onclick=""java<I>script</I>:" & vbaIIF(isBeginPage,"","history.back(1);") & """ " & vbaIIF(isBeginPage," disabled ","") & "〉上一頁〈/a〉|〈a href=""TypeOptions.asp?flbm=" & request("flbm") & "&Page=next&endID=" & endID & """〉下一頁〈/a〉")
else
'這裡通過判斷記錄集是否為空白來解決到末尾頁還可以繼續翻頁的問題
if not isBeginPage then
'判斷是否為空白記錄,並且不是起始頁,那麼產生回退頁面的指令碼,效果就是進入該頁後將自動返回到上頁。
response.Write "〈<I>script</I> language=java<I>script</I>〉" & vbCrlf
Response.W



相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。