賈瑞鳳++馬曾
摘要:建立高性能的網站,離不開ASP與數據庫之間處理性能的優化,本質上就是設法降低Web服務器執行ASP頁面的開銷以及數據庫服務器的負擔。在優化過程中重點考慮創建數據庫連接池,使用直接的OLE DB驅動程序,正確設置Command、Recordset的參數值,在內存中緩存ADO對象或其內容,使用優化過的SQL語句等。
關鍵詞:數據庫 ASP Connection Command Recordset
中圖分類號:TP31 文獻標識碼:A 文章編號:1007-9416(2014)08-0077-02
隨著Web數據庫的應用越來越多,用戶對訪問Web數據庫頁面的速度要求也越來越高。訪問Web頁面速度的快慢不僅取決于網絡的速度、Web頁面所在服務器的性能,還取決于Web頁面本身的設計等多方面原因。因為大部分網站信息都存儲在數據庫中,而且典型的ASP頁面工作原理是從后臺數據庫中檢索數據,然后將結果以HTML的形式向客戶端輸出,所以,要提高Web服務器的響應速度,建立高性能的網站,離不開ASP與數據庫之間處理性能的優化。優化的原則就是設法降低Web服務器執行ASP頁面的開銷以及數據庫服務器的負擔。
1 數據庫連接優化
在WEB程序應用中,建立數據庫連接會開銷大量資源,同時,用戶還需要一段等待連接的時間。如果很多用戶在訪問不同頁面時都需要執行建立數據庫連接,系統有可能會由于資源消耗過大而停止響應。因此,考慮用戶建立一個連接,而且不同用戶在訪問網站不同頁面時可以重復使用這一個數據庫連接,而不是再重新建立連接,就可以解決數據庫連接造成資源開銷大的問題,從而提高整個系統的性能。在IIS十ASP處理體系中,可以采用連接池(Connection poo1)機制來保證。
連接池原理:在IIS+ASP中建立一個存放數據庫連接的緩沖池,存放在緩沖池中數據庫連接是物理連接的,并且在其中被維護。當執行ASP程序中時,斷開數據庫連接是邏輯斷開。因此,當下一個用戶訪問時,就可以直接從連接沖池中應用數據庫連接,而不需再次連接數據庫,這樣可以極大地提高系統響應速度。可使用以下方法對數據庫連接進行操作:
(1)創建連接對象,Set conn=Sever.CreateObject("ADODB.connection")。
(2)建立連接,conn.open Application(“strConn”),……
(3)進行數據庫操作:……
(4)關閉連接對象:conn.close。
2 數據庫命令的優化
Command對象的功能是執行數據庫操作,對它的優化也可以提高數據庫操作效率。
2.1 正確設置CommandType屬性
適當設置CommnandType屬性提高SQL語句執行效率需要注意:
(1)執行普通的SQL語句用adCmdText。
如:ObjCmd.Execute "SELECT * FROM User WHERE [Name]=trfsoft",adCmdText
(2)選取一個表的所有字段用adCmdTable。
如:ObjCmd.Execute "SELECT * FROM table_name", adCmdText
可替換為:ObjCmd.Execute "table_name", adCmdTable
(3)執行存儲過程使用adCmdStoredProc。
如:ObjCmd.Execute "Exec proceuure_name", adCmdText
可替換為:ObjCmd.Execute "proceuure_name", adCmdStoredProc
(4)沒有返回值的數據庫操作用adExcuteNoRecords。
很重要的一點是,如果SQL語句沒有返回記錄集,如INSERT和UPDATE等,那么使用adExecuteNoRecords(ADO2.0以后版本)可以降低系統開銷。
2.2 設置Prepared屬性預編譯SQL語句
當重復執行SQL語句時,可以設置Comnand.Prepared屬性為Ture來預編譯SQL語句,通過這種方式提高的效率也很可觀,如下面的代碼:
3 對記錄集RecordSet的優化
RecordSet對象用來操作一個記錄集,它有三個與性能關系比較重要的屬性,分別是LockType、CusorType和CursorLocation,這三個屬性的設置對RecordSet的性能影響特別大。
3.1 正確設置LockType屬性
LockType屬性是指對記錄集的鎖定方式,它的取值有以下幾種:
adLockReadOnly:默認值,以只讀方式打開數據源,因而無法更改或刪除數據。
adLockPessimistic:在打開記錄集時立即鎖定數據源。此時,其他用戶不能訪問該數據庫。
adLockOptimistic:只在調用Update方法時鎖定記錄,鎖定期間其他用戶不能訪問該數據庫,Update執行完畢后自動解鎖。
adLockBatchOptimistic:用于成批更新數據,與UpdateBatch方法相對應。
LockType屬性默認是adLockReadOnly,如果不用修改數據,就不要改成adLockOptimistic之類的,否則也會降低速度和增加開銷。在使用時只要夠用即可,以減小系統開銷,提高效率。它們的系統開銷由小到大依次如下:
adLockReadOnly < adLockPessimistic < adLockOptimistic < adLockBatchOptimistic
3.2 正確設置CursorType屬性
CursorType屬性是指記錄集的游標類型,它的取值有以下幾種:
adOpeoForwardOnly:默認值,只能在記錄中向前滾動,這可以節省資源并提高性能,但此時只能調用MoveNext,無法調用MoveFoWard和RecordCount。
adOpenDynamic:可以看見其他用戶所做的添加、更改和刪除操作。允許在記錄集中進行所有類型的移動。
adOpenKeyset:與adOpenDynamic相似,不同的只是禁止查看其他用戶添加的記錄,并禁止訪問其他用戶刪除的記錄,其他用戶所做的數據更改將依然可見。
adOpenStatic:可以用來查找數據或生成報告的記錄集的靜態副本。另外,對其他用戶所做的添加、更改或刪除操作不可見。
CursorType屬性默認是adOpenForwardOnIy,如果只用MoveNextMethod,最好不要修改,但如果想使用RecordCount屬性,只能用adOpenKeyset或adOpenStatic。它們的系統開銷由小到大依次如下:
adOpeoForwardOnly < adOpenDynamic < adOpenKeyset < adOpenStatic
3.3 正確設置CursorLocation屬性
CursorLocation屬性默認是adUseSever,其實這樣不好,它可以隨時反映數據庫服務器上的改動,使得系統開銷很大,而且需要維持和數據庫服務器的連接,但是數據庫服務器和Web Server在一起的時候要快些。如果對數據的實時性沒有要求的話,則盡量使用adUseClient,使用adUseClient時可以對數據做再排序、篩選操作。
經過對上面三個屬性的解釋和分析,在使用時可以注意以下事項:
(1)檢索數據,使用默認值。
(2)更新一條數據,則LockTyPe屬性使用adLockOptimistic;成批更新數據,則LockType屬性使用adLockBatchOptimistic。
(3)寫入數據庫,CursorType屬性一般使用adOpenKeyset。
(4)用RecordCount屬性來獲得記錄總數,CursorType設置為adOpenKeyset或adOpenStatic。
4 其它優化方法
4.1 在內存中緩存ADO對象或其內容
無論數據庫的速度如何,從內存中檢索數據要比從后臺數據庫檢索數據快得多,而且從本地硬盤讀取數據通常也比從數據庫中檢索數據快,所以事先把一些常用信息存放在內存中,當用戶訪問時,直接從內存中取出,提交給用戶,以減小系統壓力,提高響應速度。例如,把獲得數據的RecordSet對象存放在Application變量中,用戶訪問時,直接從Application變量中獲取RecordSet對象;也可以將RecordSet對象數據存放在數組中,然后再將數組存儲在Application變量中,使用時用數組的方式讀取等。
緩存是典型的以空間換取時間的做法。如果緩存的內容正確,那么可以看到性能會有顯著的提高。為使緩存有效,必須保存那些經常重復使用的,并且重新計算需要付出較大代價的數據。如果緩存的都是不常用的數據,反而會造成內存浪費。
4.2 使用存儲過程
在站點中,可能存在多次查詢大量信息,用于判斷,然后更新入庫。這種情況如果在編寫ASP時,直接在一個程序中多次操作數據庫,不僅需要IIS創建很多ADO對象,加大開銷,而且還會加重數據庫服務器的負擔,增大網絡流量。如果把多次數據庫操作流程定義為一個存儲過程,用如下方式調用:
Objcmd.Execute "Exec proceuure_name" , adCmdText
就可以利用數據庫本身的強大性能,減輕Web服務器的壓力,而且由于頁面內容與業務分開,管理維護也變得方便。
4.3 僅選擇所需的字段
使用ADO記錄集中的數據表時,盡量避免自動使用表名(即SELECT*),除非想使用其中所有字段中的數據。如果只選擇需要的字段,將減少發送到服務器或從服務器取出的數據量。即使需要使用全部字段列,單獨命名每個字段列也會獲得最佳的性能,因為服務器不必再解釋這些列的名字。
4.4 使用優化過的SQL語句
在ASP技術中,ADO對象會消耗大量資源,執行一個SQL語句需要很長時間,一直占用整個資源,導致系統不能有足夠的資源為其他用戶服務。ADO是通用對象控件,沒有利用數據庫的特性。如果結合數據庫特性來編寫ASP程序,可以有效地釋放資源。例如,對于已經執行過的Sql語句,Oracle數據庫服務器通常都經過了分析優化,并存儲在一個Sql內存緩沖區中,當下次接收到同樣的sql語句請求時,直接從內存緩沖區取出執行,不再進行分析優化,從而可以大幅度提高性能。這就要求編寫ASP程序時,盡量使用相同的Sql語句,或者參數化的Sql語句,比如,不使用在IN語句中包含子查詢的語句,充分利用索引,設置Command.Prepared屬性預編譯SQL語句:
Set cmd=Server.createobject(“adodb.command”)
cmd.CommandText=”select * from product where productcode=?”
4.5 需用時創建,用完即釋放
ADO對象是非常消耗資源的,因此,只有在用到ADO對象時再創建它,用完后馬上釋放:
set rs=Server.createobject(“adodb.recordset”)
….
rs.close
set rs=nothing
對數據庫的優化處理可以使Web頁面的瀏覽速度在其它條件不變的情況下得到大大提升,在大型網站中數據庫的優化顯得龍為重要。
參考文獻
[1]郭瑞軍,李杰,初曉璐.數據庫開發實例精粹[M].北京.電子工業出版社,2005.05.
[2]頊宇峰,馬軍.ASP網絡編程從入門到精通[M].北京.清華大學出版社,2006.07.
[3]周興華,王敬棟.ASP+Access數據庫開發與實例[M].北京.清華大學出版社,2006.09.
adLockReadOnly < adLockPessimistic < adLockOptimistic < adLockBatchOptimistic
3.2 正確設置CursorType屬性
CursorType屬性是指記錄集的游標類型,它的取值有以下幾種:
adOpeoForwardOnly:默認值,只能在記錄中向前滾動,這可以節省資源并提高性能,但此時只能調用MoveNext,無法調用MoveFoWard和RecordCount。
adOpenDynamic:可以看見其他用戶所做的添加、更改和刪除操作。允許在記錄集中進行所有類型的移動。
adOpenKeyset:與adOpenDynamic相似,不同的只是禁止查看其他用戶添加的記錄,并禁止訪問其他用戶刪除的記錄,其他用戶所做的數據更改將依然可見。
adOpenStatic:可以用來查找數據或生成報告的記錄集的靜態副本。另外,對其他用戶所做的添加、更改或刪除操作不可見。
CursorType屬性默認是adOpenForwardOnIy,如果只用MoveNextMethod,最好不要修改,但如果想使用RecordCount屬性,只能用adOpenKeyset或adOpenStatic。它們的系統開銷由小到大依次如下:
adOpeoForwardOnly < adOpenDynamic < adOpenKeyset < adOpenStatic
3.3 正確設置CursorLocation屬性
CursorLocation屬性默認是adUseSever,其實這樣不好,它可以隨時反映數據庫服務器上的改動,使得系統開銷很大,而且需要維持和數據庫服務器的連接,但是數據庫服務器和Web Server在一起的時候要快些。如果對數據的實時性沒有要求的話,則盡量使用adUseClient,使用adUseClient時可以對數據做再排序、篩選操作。
經過對上面三個屬性的解釋和分析,在使用時可以注意以下事項:
(1)檢索數據,使用默認值。
(2)更新一條數據,則LockTyPe屬性使用adLockOptimistic;成批更新數據,則LockType屬性使用adLockBatchOptimistic。
(3)寫入數據庫,CursorType屬性一般使用adOpenKeyset。
(4)用RecordCount屬性來獲得記錄總數,CursorType設置為adOpenKeyset或adOpenStatic。
4 其它優化方法
4.1 在內存中緩存ADO對象或其內容
無論數據庫的速度如何,從內存中檢索數據要比從后臺數據庫檢索數據快得多,而且從本地硬盤讀取數據通常也比從數據庫中檢索數據快,所以事先把一些常用信息存放在內存中,當用戶訪問時,直接從內存中取出,提交給用戶,以減小系統壓力,提高響應速度。例如,把獲得數據的RecordSet對象存放在Application變量中,用戶訪問時,直接從Application變量中獲取RecordSet對象;也可以將RecordSet對象數據存放在數組中,然后再將數組存儲在Application變量中,使用時用數組的方式讀取等。
緩存是典型的以空間換取時間的做法。如果緩存的內容正確,那么可以看到性能會有顯著的提高。為使緩存有效,必須保存那些經常重復使用的,并且重新計算需要付出較大代價的數據。如果緩存的都是不常用的數據,反而會造成內存浪費。
4.2 使用存儲過程
在站點中,可能存在多次查詢大量信息,用于判斷,然后更新入庫。這種情況如果在編寫ASP時,直接在一個程序中多次操作數據庫,不僅需要IIS創建很多ADO對象,加大開銷,而且還會加重數據庫服務器的負擔,增大網絡流量。如果把多次數據庫操作流程定義為一個存儲過程,用如下方式調用:
Objcmd.Execute "Exec proceuure_name" , adCmdText
就可以利用數據庫本身的強大性能,減輕Web服務器的壓力,而且由于頁面內容與業務分開,管理維護也變得方便。
4.3 僅選擇所需的字段
使用ADO記錄集中的數據表時,盡量避免自動使用表名(即SELECT*),除非想使用其中所有字段中的數據。如果只選擇需要的字段,將減少發送到服務器或從服務器取出的數據量。即使需要使用全部字段列,單獨命名每個字段列也會獲得最佳的性能,因為服務器不必再解釋這些列的名字。
4.4 使用優化過的SQL語句
在ASP技術中,ADO對象會消耗大量資源,執行一個SQL語句需要很長時間,一直占用整個資源,導致系統不能有足夠的資源為其他用戶服務。ADO是通用對象控件,沒有利用數據庫的特性。如果結合數據庫特性來編寫ASP程序,可以有效地釋放資源。例如,對于已經執行過的Sql語句,Oracle數據庫服務器通常都經過了分析優化,并存儲在一個Sql內存緩沖區中,當下次接收到同樣的sql語句請求時,直接從內存緩沖區取出執行,不再進行分析優化,從而可以大幅度提高性能。這就要求編寫ASP程序時,盡量使用相同的Sql語句,或者參數化的Sql語句,比如,不使用在IN語句中包含子查詢的語句,充分利用索引,設置Command.Prepared屬性預編譯SQL語句:
Set cmd=Server.createobject(“adodb.command”)
cmd.CommandText=”select * from product where productcode=?”
4.5 需用時創建,用完即釋放
ADO對象是非常消耗資源的,因此,只有在用到ADO對象時再創建它,用完后馬上釋放:
set rs=Server.createobject(“adodb.recordset”)
….
rs.close
set rs=nothing
對數據庫的優化處理可以使Web頁面的瀏覽速度在其它條件不變的情況下得到大大提升,在大型網站中數據庫的優化顯得龍為重要。
參考文獻
[1]郭瑞軍,李杰,初曉璐.數據庫開發實例精粹[M].北京.電子工業出版社,2005.05.
[2]頊宇峰,馬軍.ASP網絡編程從入門到精通[M].北京.清華大學出版社,2006.07.
[3]周興華,王敬棟.ASP+Access數據庫開發與實例[M].北京.清華大學出版社,2006.09.
adLockReadOnly < adLockPessimistic < adLockOptimistic < adLockBatchOptimistic
3.2 正確設置CursorType屬性
CursorType屬性是指記錄集的游標類型,它的取值有以下幾種:
adOpeoForwardOnly:默認值,只能在記錄中向前滾動,這可以節省資源并提高性能,但此時只能調用MoveNext,無法調用MoveFoWard和RecordCount。
adOpenDynamic:可以看見其他用戶所做的添加、更改和刪除操作。允許在記錄集中進行所有類型的移動。
adOpenKeyset:與adOpenDynamic相似,不同的只是禁止查看其他用戶添加的記錄,并禁止訪問其他用戶刪除的記錄,其他用戶所做的數據更改將依然可見。
adOpenStatic:可以用來查找數據或生成報告的記錄集的靜態副本。另外,對其他用戶所做的添加、更改或刪除操作不可見。
CursorType屬性默認是adOpenForwardOnIy,如果只用MoveNextMethod,最好不要修改,但如果想使用RecordCount屬性,只能用adOpenKeyset或adOpenStatic。它們的系統開銷由小到大依次如下:
adOpeoForwardOnly < adOpenDynamic < adOpenKeyset < adOpenStatic
3.3 正確設置CursorLocation屬性
CursorLocation屬性默認是adUseSever,其實這樣不好,它可以隨時反映數據庫服務器上的改動,使得系統開銷很大,而且需要維持和數據庫服務器的連接,但是數據庫服務器和Web Server在一起的時候要快些。如果對數據的實時性沒有要求的話,則盡量使用adUseClient,使用adUseClient時可以對數據做再排序、篩選操作。
經過對上面三個屬性的解釋和分析,在使用時可以注意以下事項:
(1)檢索數據,使用默認值。
(2)更新一條數據,則LockTyPe屬性使用adLockOptimistic;成批更新數據,則LockType屬性使用adLockBatchOptimistic。
(3)寫入數據庫,CursorType屬性一般使用adOpenKeyset。
(4)用RecordCount屬性來獲得記錄總數,CursorType設置為adOpenKeyset或adOpenStatic。
4 其它優化方法
4.1 在內存中緩存ADO對象或其內容
無論數據庫的速度如何,從內存中檢索數據要比從后臺數據庫檢索數據快得多,而且從本地硬盤讀取數據通常也比從數據庫中檢索數據快,所以事先把一些常用信息存放在內存中,當用戶訪問時,直接從內存中取出,提交給用戶,以減小系統壓力,提高響應速度。例如,把獲得數據的RecordSet對象存放在Application變量中,用戶訪問時,直接從Application變量中獲取RecordSet對象;也可以將RecordSet對象數據存放在數組中,然后再將數組存儲在Application變量中,使用時用數組的方式讀取等。
緩存是典型的以空間換取時間的做法。如果緩存的內容正確,那么可以看到性能會有顯著的提高。為使緩存有效,必須保存那些經常重復使用的,并且重新計算需要付出較大代價的數據。如果緩存的都是不常用的數據,反而會造成內存浪費。
4.2 使用存儲過程
在站點中,可能存在多次查詢大量信息,用于判斷,然后更新入庫。這種情況如果在編寫ASP時,直接在一個程序中多次操作數據庫,不僅需要IIS創建很多ADO對象,加大開銷,而且還會加重數據庫服務器的負擔,增大網絡流量。如果把多次數據庫操作流程定義為一個存儲過程,用如下方式調用:
Objcmd.Execute "Exec proceuure_name" , adCmdText
就可以利用數據庫本身的強大性能,減輕Web服務器的壓力,而且由于頁面內容與業務分開,管理維護也變得方便。
4.3 僅選擇所需的字段
使用ADO記錄集中的數據表時,盡量避免自動使用表名(即SELECT*),除非想使用其中所有字段中的數據。如果只選擇需要的字段,將減少發送到服務器或從服務器取出的數據量。即使需要使用全部字段列,單獨命名每個字段列也會獲得最佳的性能,因為服務器不必再解釋這些列的名字。
4.4 使用優化過的SQL語句
在ASP技術中,ADO對象會消耗大量資源,執行一個SQL語句需要很長時間,一直占用整個資源,導致系統不能有足夠的資源為其他用戶服務。ADO是通用對象控件,沒有利用數據庫的特性。如果結合數據庫特性來編寫ASP程序,可以有效地釋放資源。例如,對于已經執行過的Sql語句,Oracle數據庫服務器通常都經過了分析優化,并存儲在一個Sql內存緩沖區中,當下次接收到同樣的sql語句請求時,直接從內存緩沖區取出執行,不再進行分析優化,從而可以大幅度提高性能。這就要求編寫ASP程序時,盡量使用相同的Sql語句,或者參數化的Sql語句,比如,不使用在IN語句中包含子查詢的語句,充分利用索引,設置Command.Prepared屬性預編譯SQL語句:
Set cmd=Server.createobject(“adodb.command”)
cmd.CommandText=”select * from product where productcode=?”
4.5 需用時創建,用完即釋放
ADO對象是非常消耗資源的,因此,只有在用到ADO對象時再創建它,用完后馬上釋放:
set rs=Server.createobject(“adodb.recordset”)
….
rs.close
set rs=nothing
對數據庫的優化處理可以使Web頁面的瀏覽速度在其它條件不變的情況下得到大大提升,在大型網站中數據庫的優化顯得龍為重要。
參考文獻
[1]郭瑞軍,李杰,初曉璐.數據庫開發實例精粹[M].北京.電子工業出版社,2005.05.
[2]頊宇峰,馬軍.ASP網絡編程從入門到精通[M].北京.清華大學出版社,2006.07.
[3]周興華,王敬棟.ASP+Access數據庫開發與實例[M].北京.清華大學出版社,2006.09.