幾乎所有關於ado資料庫訪問效能分析的文章,都認為二進位制元件的效能總是超過解釋執行的asp**。事實上,這是錯誤的。從本文的測試結果可以看出,有些時候asp**的效能遠遠超過了元件。
一、引言
「地球是平坦的...」;
「太陽繞著地球轉...」;
「總是通過元件訪問資料庫...」,
上面三個命題有兩個共同的特點:首先,它們都曾經被認為是正確的;其次,這三個命題實際上都是錯誤的。
我們都已經讀到過無數的文章建議在inter***應用中用元件封裝業務邏輯和進行資料庫訪問,但有關這種技術的實際效能資料卻很少看到。隨著windows 2000的發行,iis平台特別是asp的效能表現也有了顯著的提高。由於先行繫結(early-binding)內部物件、模板緩衝等諸多改進,在通過ado訪問資料庫、格式化並輸出記錄集等各個方面,asp都有一流的效能表現。
從本文測試結果可以看出,asp在ado資料庫訪問、記錄集格式化方面勝過元件,而且在某些情形下兩者的差異達到了難以置信的程度。對於大多數inter***應用來說,效能總是首要因素,所以在根據傳聞或書本知識確定最優方案之前,使用測試工具對方案進行完整的測試是很重要的。
在進行測試之前,本文的所有三組**(asp,vb和c++)都經過了優化。為了確保參與測試的**其編碼方法和測試結果都是各自領域中最優的,它們都經過了多次測試。某些優化工作尚未進行,這是為了讓**更真實地反映出實際應用環境中可能出現的典型情況。
二、測試環境
本次測試只在windows 2000平台上進行,在windows nt平台上測試結果可能會有很大的不同,所以測試所得到的結果不適用於windows nt平台。下面是本次測試所用系統的示意圖及其說明:
由於測試客戶機和web伺服器、資料庫伺服器所處的物理位置不同,客戶機通過三個cisco 2924交換機連線到web伺服器。所有這些機器都在同一大樓內,但伺服器位於資料中心,而測試客戶機位於另乙個房間,客戶機通過乙個400mb fast etherchannel連線到資料中心的交換機。
在這個配置下,測試案例的網路延遲所引起的開銷是非常小的。在日常執行中交換機之間的流量總是小於其能力的5%。
三、測試**
使用odbc dsn建立/開啟乙個資料庫連線
建立乙個***mand物件(設定其型別為adcmdstoreproc)
指定返回記錄數量的引數
執行命令,返回記錄集
關閉記錄集和連線,釋放這些物件占用的記憶體。
可以證實上述方法具有最快的資料庫訪問速度,這是因為:
儲存過程訪問速度要比動態sql快,即使啟用了sqlserver 7.0的sql計畫快取功能也一樣。
使用***mand物件並顯式地指定引數要比傳入乙個查詢字串快得多,這是因為此時oledb提供者無需分析查詢型別以及所有傳遞給儲存過程的引數的型別。
odbc連線池避免了為每乙個開啟命令建立物理連線。每次關閉連線將把已開啟的連線釋放回連線池。
結構,這是為了能夠讓測試程式更加精確地模擬出實際的記錄集處理過程。
返回給客戶端的html**是從乙個兩列的記錄集建立的結構。所有測試程式都用while迴圈遍歷記錄集,而不是用速度更快的getstring方法直接從記錄集資料得到結構,這是為了能夠讓測試程式更加精確地模擬出實際的記錄集處理過程。
測試所用的儲存過程從表中提取記錄,返回記錄的數量以引數形式傳遞給儲存過程。
測試以多種不同的記錄數量和執行緒數量(併發請求數量)執行。記錄數量的範圍從0行到100行,但沒有測試超過100行的返回記錄數量,這是因為考慮到大多數設計良好的web應用不會出現如此大規模的記錄集資料提取和格式化操作。
所有測試指令碼均在網路利用率最低的時候執行。此外,測試期間iis/***+伺服器和sql server上都沒有進行其他操作。
iis的「應用程式保護」設定成「低」,這使得應用執行具有最好的效能,特別是對***+庫應用的測試來說尤其如此。這個設定同時也允許了所有任務在i***info程序內執行。
參與測試的五種程式為:asp,vb元件(***+的庫應用),c++元件(***+的庫應用),vb元件(***+的伺服器應用),c++元件(***+的伺服器應用)。
在所有測試程式中,測試客戶機的負載一直沒有超過35%的處理器利用率,而且記憶體占用也很少。
有部分優化工作沒有做,這是為了讓測試**更好地反映出當前的主流應用。例如,本文測試利用odbc系統dsn建立資料庫連線,把連線改用oledb的sql server提供者將使整體效能提高大約5-10%。
四、測試結果
也許你已經從本文的題目猜出本次測試的獲勝者應該是asp了。下面我們來看看具體的測試結果,**從這些測試資料得到的結論。
本次測試的主要統計專案如下所示:
第一組測試中記錄集的記錄數量設定為10,執行緒數量在25到2000之間變化。效能的主要度量標準,即requests per seconds結果如下所示:
從上圖可以看出,asp在效能上比和它最接近的對手vb (in proc — 程序內,即***+庫應用)平均快30%,比其他方法要快2倍以上。值得指出的是,vb(in-proc)的效能隨著執行緒數量的增加而略有增加。然而,當執行緒數量超過大約250之後,ttfp和asp requests queued已經高得不再對單個伺服器的正常操作具有任何意義。實際上,許多人會認為即使是250也太高了。因此,在記錄數量更多的測試中線程數量最大值不超過250。
測試工具的指令碼執行不產生任何延遲。因此,只要對某個執行緒的應答一到達,新的請求總是立即發出。
在分析記錄數量更多的測試結果之前,我們先來看看其它兩個測試指標ttfb和hits的測試結果。
正如我們可以預料的那樣,asp在所有執行緒數量配置下都具有較快的ttfb。下表比較負載的增加對asp requests queued以及相應的ttfb的影響,所有資料都以requests queued -ttfp形式給出,ttfb仍舊以毫秒計。
可以看出,當負載高達一定程度(~50-100執行緒範圍)時就有必要加入更多的伺服器來分擔流量。不過本文測試仍舊包含這些高負載的情形,這是為了觀察是否有可能出現不同的變化。
最後乙個效能度量標準hits的測試結果也顯示出和其餘測試相同的傾向,asp的表現仍舊是最優秀的。
下乙個測試步驟是觀察當記錄集的記錄數量增加時各個測試程式的效能表現。這裡所測試的記錄數量包括:20,30,50,和100。如果你讀過大量這方面的文章,可能會猜想由於記錄數量的增加處理負載也隨之增加,元件將表現出更好的效能。然而,事實並非如此。記錄數量逐步增加時asp仍舊保持著對其他各種方法的領先優勢。下面是不同執行緒數量平均後的測試結果。
五、結果分析
總地看來,在windows 2000平台上沒有一種採用元件的方法能夠在純ado操作的效能上超過asp。雖然以***+庫應用形式執行的元件相比之下更接近asp(而且也應該如此),但它們與asp表現出的效能相比仍略有不足。事實上,即使是程序內執行的vb元件的效能也比asp的差30%。然而,為了在應用所執行的元件產生錯誤時保護i***info程序,許多應用仍舊在乙個專用的服務程序(dllhost.exe)內執行它們的***+應用,在這種常見的情況下,asp可以提供2比1的效能優勢!
我們希望本文已經成功地說明了這樣乙個問題:在乙個inter***應用中利用元件進行資料庫訪問並非一定是最好的方案。務必在深入實施某個方案之前進行完整的測試,這一點極其重要,因為該方案的最終結果可能會和你所設想的(或你所看到、聽到的)完全不同。
如果inter***應用的規模屬於中等或比較大,效能將成為首要的考慮因素,比**的可重用性更為重要。但現實當中主要的應用程式很少(如果有的話)同時也是效能方面的最優方案。
當然,使用元件也有它的好處。元件往往是封裝某些型別的業務邏輯的最好選擇,特別是在跨系統整合的應用中。然而在有些情形下這似乎走入了乙個極端,返回來更深入地了解一下現有的技術平台、根據應用的業務情況真正地理解資料的處理、匯集和傳輸過程,這才是明智的。許多時候我們會發現奧鏗剃刀原理掌握了真理:在涉及到複雜的系統時,最簡單的解決方法往往就是最好的解決方法(而且很可能是最容易測量的方法!)。
雖然本文只涉及了有限的ado資料庫訪問操作,以更複雜的指令碼和元件所作的類似測試也得到了同樣的結果。如果你使用的是windows 2000平台,顯然你應該考慮對方案的效能按照本文說明進行廣泛的測試。如果你的終極目標在於效能,你會發現自己把一些元件替換成了asp。或許連你自己也會對此吃驚。
ADO資料庫訪問的最優方法
ado資料庫訪問的最優方法 幾乎所有關於ado資料庫訪問效能分析的文章,都認為二進位制元件的效能總是超過解釋執行的asp 事實上,這是錯誤的。從本文的測試結果可以看出,有些時候asp 的效能遠遠超過了元件。一 引言 地球是平坦的.太陽繞著地球轉.總是通過元件訪問資料庫.上面三個命題有兩個共同的特點 ...
ADO訪問資料庫的方法
現將 ado訪問資料庫的基本步驟和方法介紹如下 第一步 在 stdafx.h 中新增 import c program files common files system ado msado15.dll no namespace rename eof adoeof 第二步 初始化 com環境 在合適...
ADO 訪問資料庫
using system using system.collections.generic using system.componentmodel using system.data using system.drawing using system.text using system.window...