明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

數(shù)據(jù)分頁方法新思路,速度10分快!

[摘要]這篇文章要達到的目的就是,實現(xiàn)大數(shù)據(jù)分頁瀏覽并最優(yōu)化速度。 建立一個web 應(yīng)用,分頁瀏覽功能必不可少;這個問題也是長久以來最普遍的問題,目前也得到了較好的解決,其中象ASP 程序的分頁算法有很多,比如使用ado 對象的PageSize 這些屬性,按記錄總數(shù)計算頁,然后跳轉(zhuǎn)記錄集再輸出;也...

這篇文章要達到的目的就是,實現(xiàn)大數(shù)據(jù)分頁瀏覽并最優(yōu)化速度。

    建立一個web 應(yīng)用,分頁瀏覽功能必不可少;這個問題也是長久以來最普遍的問題,目前也得到了較好的解決,其中象ASP 程序的分頁算法有很多,比如使用ado 對象的PageSize 這些屬性,按記錄總數(shù)計算頁,然后跳轉(zhuǎn)記錄集再輸出;也有編寫存儲過程實現(xiàn)分頁數(shù)據(jù),這些方面各有優(yōu)缺點,以下本人介紹一種應(yīng)用實際項目中速度非?斓姆猪撍惴;

關(guān)鍵點:SQL (用TOP 和 自動編號 實現(xiàn))
        頁面腳本 (瀏覽器回退功能)

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

實現(xiàn)原理:
  這個表設(shè)定了自動編號字段,這個字段的特性就是生成不重復(fù)的整形,包括刪除了記錄后該字段仍然保持‘流水性’(注:通常在系統(tǒng)表建設(shè)中,這種字段的運用很少,因為編號不能自由管理,但在這里使用它,主要是想在文章中省略編號維護的代碼)。

分頁:
  那么第一步,就是查詢一個頁的數(shù)據(jù);如果有100筆記錄,按20記錄一頁,那么通常的分頁算法就是“頁總數(shù)=總記錄 除 分頁的控制數(shù) [有余數(shù)的話,頁總數(shù)加一]”,這樣的做法就導(dǎo)致必須產(chǎn)生所有記錄的一個大記錄集;從而,又有人提出了用存儲過程的分頁算法,前者是asp 腳本產(chǎn)生大記錄集,這樣速度相當慢,后者是殺雞用牛刀,雖然我經(jīng)常寫存儲過程,但根據(jù)我的思路會發(fā)現(xiàn)寫存儲過程完全多余。
  
  在SQL 中,許多剛接觸它的朋友都知道 Top 修飾關(guān)鍵字的作用;例如:select TOP 1 * from table1 --這樣就實現(xiàn)從Table1表返回只有一條記錄的記錄集那么分頁優(yōu)化的最終目的就是避免產(chǎn)生過大的記錄集,通過TOP 即可完全控制;現(xiàn)在查詢表應(yīng)該是 select Top 20 自動編號,標題,內(nèi)容,時間 from 內(nèi)容表。
  
  但現(xiàn)在還有個問題,就是如何定位,Top 不可能自動給我們定位輸出某個頁,這就設(shè)計到了where 從句,根據(jù)一個特定條件輸出正確的內(nèi)容;注意:記錄的 order by 排序是非常重要的,這個決定了這個算法的成。
  
這里的演示是DESC 方式,倒序排列,比如網(wǎng)站的軟件更新,就是最近的更新放最前面,而這個就是倒序方式。

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


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

    '打開數(shù)據(jù)連接執(zhí)行SQL 并建立記錄集
    set rs = Cnn.Execute(strSQL)
    if not rs.Eof then '這里寫入判斷是否為Eof 可以不要,但是,在這里卻有它的特殊意義
      call TableTitle '這里是自寫的函數(shù),用于建立表格標記
        call beginTr '這里是建立表格tr標記

        for i=0 to rs.fields.Count-1 '遍歷記錄集字段
          call AddCol(rs(i).name) '輸出字段名
        Next
        
        call endTr      

        while not rs.eof      '循環(huán)記錄集內(nèi)容,并輸出
          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     '到此為止,就簡單的將記錄集內(nèi)容全部輸出
      '這里輸出翻頁標記,vbaIIF 是自寫函數(shù)
       原型為 <I>function</I> vbaIIF(a,b,c)
                if a then
                  vbaIIF =b
                else
                  vbaIIF =c
                end if
              end <I>function</I>
      
       上一頁的實現(xiàn)是通過腳本調(diào)用瀏覽器的功能 history.back(1) 實現(xiàn),那么回頁時并不需要在服務(wù)器端重新生成數(shù)據(jù),速度不用考慮了。
       在首頁的時候,上一頁的鏈接應(yīng)該是無效的,通過 vbaIIF(isBeginPage,"disabled","") 實現(xiàn),如果為首頁,那么在標記中加入 disabled 屬性 ,如果不是首頁,則加入history.back(1); 腳本指令,用于回退瀏覽頁。
       下一頁是傳遞Page 參數(shù)和endID參數(shù),Page 設(shè)置為 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
     '這里通過判斷記錄集是否為空來解決到末尾頁還可以繼續(xù)翻頁的問題
      if not isBeginPage then
       '判斷是否為空記錄,并且不是起始頁,那么生成回退頁面的腳本,效果就是進入該頁后將自動返回到上頁。       
        response.Write "〈<I>script</I> language=java<I>script</I>〉" & vbCrlf
        Response.Write "history.back(1);" & vbCrlf
        Response.Write "〈/<I>script</I>〉"
        Response.End
      else '如果是起始頁記錄就為空,則提示無內(nèi)容
        Response.Write "〈font color=blue〉該類別下無內(nèi)容〈/font〉"
      end if
    end If


總結(jié):通過前臺腳本,SQL查詢技巧,實現(xiàn)高性能的分頁程序簡單快速

希望同行提出更優(yōu)秀實時數(shù)據(jù)分頁算法

備注:由于論壇限制了HTML字符,所以關(guān)鍵符號采用了中文大寫。