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

2021-03-31 08:56:59 字數 3716 閱讀 3456

從圖中可以看出,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

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

asp.net提供了乙個datagrid控制項可以比以前的asp方便地建立建立資料列表,datagrid控制項除了內建的資料表現和方法之外,還允許使用者自己定義表現形式。分頁技術為使用者可管理的資料查詢提供方便。datagrid內建的分頁技術很 容易實現,但資料量很大時,它的方便性是以犧牲效能為代價...

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

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

利用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...