利用自定義分頁技術提高資料庫效能

2021-04-12 14:34:48 字數 4019 閱讀 8487

asp.net提供了乙個datagrid控制項可以比以前的asp方便地建立建立資料列表,datagrid控制項除了內建的資料表現和方法之外,還允許使用者自己定義表現形式。分頁技術為使用者可管理的資料查詢提供方便。datagrid內建的分頁技術很 容易實現,但資料量很大時,它的方便性是以犧牲效能為代價的。下面,我們就看看如何通過自定義的分頁方法來實現快速處理大量資料的結果集的辦法。我們這裡討論的方法比datagrid的預設分頁方法是快速和更加有效的,這是因為每次請求不需要把全部的資料結果傳送到web伺服器。相反,它只需要傳送每個頁面需要的那些資料集。例如:如果乙個使用者只要求100個頁面中每頁顯示25條記錄的第4頁的結果集,伺服器只需要傳送第75-100行的資料即可,而不是1-1000行的完全資料。預設的傳送方式如圖1所示:

從圖中可以看出,datagrid的內建分頁方法是效率不高的,每次請求都必須把整個查詢結果傳送給web伺服器,web伺服器再把資料分成相應的頁面。利用datagrid的內建的分頁方法儘管是很簡單的,但是,由於web應用的無序性特徵,乙個使用者每次從乙個頁面轉向另外乙個頁面時,datagrid物件都被銷毀並重新建立,這就意味著資料庫伺服器每次都必須傳送全部的結果集。

自定義的分頁方法只返回所要檢索的那些結果集,如下圖2所示:

從上面的圖中可以看到,資料庫每次只需要返回所要顯示的資料記錄。首先,我們在資料庫中建立乙個儲存過程,並有兩個輸入引數,分別是要返回資料的第一條記錄數和最後一條記錄數,在sql server7.0以上的版本中,都有乙個top關鍵字限制返回到結果集中的前多少條記錄數,然而不幸的是,沒有乙個方法可以返回中間一部分的資料,例如第75條記錄到100條記錄的資料。oracle中有乙個rownum()的擴充套件函式可以返回中間的記錄,比如:"select * form authors where author_last_name = 'anderson' and rownum() >=75 and rownum() <= 100"。然而,由於oracle是在排序之前指定rownum的值,因此,這樣的查詢"select * from authors where rownum <= 25 order by author_last_name"將得不到我們期望的結果。我們下面所講的方法是針對sql server的,但這裡的概念對適合oracle開發人員也是適用的。

要建立乙個返回指定條記錄結果的儲存過程,首先必須指定返回結果集的條記錄數,可以用臨時表,也可以用table變數(sql server 2000),兩個在效能上沒有太大的差別,但是,table變數是儲存在記憶體中的,如果你的伺服器記憶體不多的話,可以考慮用臨時表,臨時表使用硬碟儲存結果,臨時表需要手工釋放物件,而table變數在儲存過程結束後自動釋放。下面就是我們要建立的儲存過程:

create proc getauthors

@author_last_name as varchar(100) = null,

@startrow as int = null,

@stoprow as int = null

as---- 建立有識別符號列的table變數

declare @t_table table

([rownum] [int] identity (1, 1) primary key not null ,

[author_last_name] [varchar] (40) ,

[author_first_name] [varchar] (20) ,

[phone] [char] (12) ,

[address] [varchar] (40) ,

[city] [varchar] (20) ,

[state] [char] (2) ,

[zip] [char] (5)

)---- 在返回指定的@stoprow行數之後停止處理查詢

set rowcount @stoprow

---- 插入到table變數中

insert @t_table

([author_last_name],[author_first_name],[phone],[address],[city],[state],[zip]

)select [author_last_name],[author_first_name],[phone],[address],[city],[state],[zip]

from authors

where author_last_name like '%' + @author_last_name + '%'

order by author_last_name

---- 返回到正確的結果

select * from @t_table where rownum >= @startrow

order by rownum

go引數@startrow和@stoprow接收整數值,代表要返回的開始記錄和結束記錄,如果要在乙個25條記錄的頁面中返回第4頁,我們就可以設定@startrow為76,@stoprow為100。我們在table變數@t_table中定義了乙個叫rownum的整數型別的列,並指定為識別符號列,這個列在我們這裡介紹的分頁技術中是很重要的,當我們插入資料時,這個列自動增加,它將在插入資料時起排序作用。set rowcount語句對優化效能很關鍵,它告訴sql server進行限制要插入的資料,如果我們要76-100條記錄之間的資料,那麼就可以不必插入大於100條記錄的資料。最後的sql語句從@t_table的table變數選擇rownum大於或者等於@startrow的那些資料集,然後把它們返回到web伺服器,由web伺服器繫結到datagrid物件。值得注意的是:如果要得到76到100條記錄的資料,我們必須往table變數中插入100條記錄的資料,這意味著:如果瀏覽者請求的頁數越來越大,頁面效能也會有所下降的。例如:要顯示第100頁的資料(從第2451條記錄到第2500條記錄),我們必須先向table變數或者臨時表填充2500條記錄,因此,效能依賴於你計算機的硬體和你要返回的記錄數,有測試表明,在sql server 2000中使用這樣的儲存過程平均在200-250毫秒內返回第100頁,而返回第一頁只需要4毫秒。即使返回第500頁的資料(從第12451到12500條記錄)也可以在650到750毫秒內完成。應該說這種情況是很少見到的。 但為了減輕資料庫和網路傳輸的壓力,設計合理的查詢結果頁數是很見效的。

現在,我們寫好了乙個儲存過程來做分頁的工作,而不是用web伺服器來做這個事情,我們接下來要做的就是為datagrid物件編寫**來使用我們的分頁技巧。datagrid的allowpaging、allowcustompaging、pagestyle屬性有助於避免我們編寫自己的**來跟蹤記錄瀏覽者目前在哪乙個頁面訪問和都請求過哪些頁面。我們應當設定allowcustompaging為true,否則,在你使用datareader或者sqldatareader繫結到datagrid物件會遇到麻煩。在任何可能的情況下,應當盡量使用sqldatareader而不要使用dataset來裝載datagrid物件。據效能測試表明:在構建列表顯示資料時,使用sqldatareader比使用dataset要快兩倍以上。不要設定allowpaging和pagestyle的值,這是因為,如果使用這兩個屬性,你必須在viewstate中維護datagrid,但為了追求效能最佳化,我們必須設定datagrid的enableviewstate屬性為false,儘管這樣我們自己必須編寫一點**來實現我們的分頁,但是效能會有所提高的,因為在每次與web伺服器打交道時不必再在viewstate中儲存內容了。

private sub buttonnext_click (byval sender as object, _

byval e as system.eventargs) handles buttonnext.click

viewstate("startrow") = viewstate("startrow") + dgrid.pagesize

viewstate("stoprow") = viewstate("startrow") + dgrid.pagesize

'執行儲存過程,返回sqldatareader

dgrid.datasource = runsprocreturndr (textau_lname.text, _

textau_fname.text, viewstate("startrow"),viewstate("stoprow"))

dgrid.databind()

end sub

利用自定義分頁技術提高資料庫效能

利用自定義分頁技術提高資料庫效能 從圖中可以看出,datagrid的內建分頁方法是效率不高的,每次請求都必須把整個查詢結果傳送給web伺服器,web伺服器再把資料分成相應的頁面。利用datagrid的內建的分頁方法儘管是很簡單的,但是,由於web應用的無序性特徵,乙個使用者每次從乙個頁面轉向另外乙個...

利用自定義分頁技術提高資料庫效能

從圖中可以看出,datagrid的內建分頁方法是效率不高的,每次請求都必須把整個查詢結果傳送給web伺服器,web伺服器再把資料分成相應的頁面。利用datagrid的內建的分頁方法儘管是很簡單的,但是,由於web應用的無序性特徵,乙個使用者每次從乙個頁面轉向另外乙個頁面時,datagrid物件都被銷...

利用ListView自定義高效分頁

建立資料庫表 tableadapter新增sql查詢語句 select from select id,title,msg,createdtime,row number over order by id rownum from dbo.t news twhere t.rownum startrowin...