2009-01-23 96 views
12

某些上下文:我正在使用的系統之一是.net 2.0 Web應用程序。 VB.net作爲前端,而SQL Server 2005作爲後端。由於各種原因已經失去了時間,原始設計師決定使用.Net OleDB連接而不是SQLClient連接。OleDB與SQLClient有什麼區別?

經過幾年的發展,這個特定的系統正處於從「測試」到「1.0」狀態的交叉點。我們在這裏談論的一件事是轉向SQLClient連接。雖然我知道使用它是最好的實踐,並且它是獲得SQL Server 2005中更好用的功能(顯然我們沒有使用)的唯一方法,但使用它的優點是什麼?其他?任何隱藏的陷阱我應該知道?任何人都可以指出我的一些基準顯示相對速度? (我聽說SQLClient應該會更快,但我從來沒有看到任何數字來支持它。)

謝謝,所有。

回答

18

OleDb更通用。如果您將來轉移到不同的數據庫類型,很可能會有一個Ole驅動程序,您不必更改太多的代碼。另一方面,如你所說,Sql Server本地驅動程序應該更快,並且它有更好的參數支持(參數可以使用名稱,並且的順序不是)。在我個人的經歷中,我從來沒有注意到速度的不同,所以就像你我找不到任何東西來支持它。我懷疑性能優勢是真實的,但是在開始測量之前,你必須處理數百萬條記錄。

我注意到,有意義的區別是錯誤信息。我遇到了一箇舊的OleDb應用程序的問題,並且我絕望地將它切換到了SqlClient。當然,它仍然不起作用,但更好的錯誤信息提供了足夠的新信息,我能夠解決這個問題。

+3

現在值得注意的是,根據我的前兩句話,微軟現在不贊成使用Ole來支持Odbc – 2011-12-24 02:49:37

3

我和Joel在這一個上,如果你打算堅持使用SQL Server,SqlClient是最好的選擇。性能有所提升,但您必須開始使用大型集合,而大量事務通常開始看到這方面的好處。總體而言,所提供的錯誤和功能更適合於SQL Server可以執行的操作,因此如果您願意,可以實現「更好」的實現。它也支持MARS,對於某些人來說它是「必做」開關。

2

您可以隨時使用SqlClient和OleDB編寫具有典型操作的示例應用程序,並對它們進行基準測試以比較性能。我懷疑這種差異會很大,但只有一種方法可以找出答案。

我不認爲你有任何問題使用OleDb,除非你使用像XML這樣的外來數據類型,在這種情況下你可能需要更努力一點。

11

OLEDB比SQLClient快得多,除了通過ADO.NET訪問時。但是,OLEDB的驅動程序是使用本機非託管代碼編寫的,當您通過ADO.NET訪問這些驅動程序時,必須經過幾個層(包括抽象層和COM互操作層)。抽象層負責管理資源管理,如管理內存句柄以確保正確地進行垃圾回收,將數據類型和參數更改爲.NET類型,並將oledb緩衝區轉換爲行和列綁定。 COM互操作層負責編碼從.NET傳遞消息到COM,反之亦然,包括鎖定/解鎖/轉換指針。

不要聽任何人誤解OleDB的性能而不理解他們如何測試它以及他們使用什麼環境(託管代碼vs託管代碼)。減少OleDB速度的唯一方法是讓本機代碼與託管代碼良好協作所需的管道數量。另外請記住,SqlClient .NET庫有自己的管道,而且不像大多數人認爲的那樣是非本地.NET庫。 .NET中的SqlClient庫使用SNINativeMethodWrapper和SNIPacket類,它們是非託管代碼(sqlncli.dll)和託管.NET代碼之間封送數據的封裝器。這是沒有證據的事實,也是爲什麼當您在本機非託管代碼中使用OleDB時,.NET SqlClient永遠無法執行OleDB的原因。

總之,如果您使用的是100%託管代碼,您將從System.data.SqlClient獲得更好的性能。如果你有一個混合的環境,你會直接與OleDB直接交談,或者與sqlncli.dll(SQL2005)或sqlncli10.dll(SQL 2008)交談。請記住,OleDB和ODBC正在由Microsoft更新,並且最新的OleDB驅動程序會與最新的非託管本機SQL客戶端庫進行通信。當需要高性能時,Microsoft建議在非託管應用程序中使用OleDB。

有關更多信息,請參閱「SQL Server 2008聯機叢書\數據庫引擎\開發\開發人員指南\ SQL Server 2008本機客戶端編程\ SQL Server 2008本機客戶端(OLE DB)」。

3

這裏是做一個直接的比較一些PowerShell的代碼:

OLE-DB:

$ConnectionString  = "server=localhost;database=MyDatabase;trusted_connection=yes;Provider=SQLNCLI10;" 
$sql = "SELECT * FROM BigTable" 

$conn = New-Object System.Data.OleDb.OleDbConnection($ConnectionString) 
$conn.open() 
$cmd = New-Object system.Data.OleDb.OleDbCommand($sql,$conn) 
#$cmd.CommandTimeout = $timeout 
$da = New-Object system.Data.OleDb.OleDbDataAdapter($cmd) 
$dt = New-Object system.Data.datatable 
[GC]::Collect() 
$start = get-date 
[void]$da.fill($dt) 
$now = get-date 
[int]($now - $start).Milliseconds 
$conn.close() 
#$dt 

SQLCLIENT:

$ConnectionString  = "Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=True" 
$sql = "SELECT * FROM BigTable" 


$conn=new-object System.Data.SQLClient.SQLConnection($ConnectionString) 
$conn.Open() 
$cmd=new-object System.Data.SQLClient.SQLCommand($sql,$conn) 
# $cmd.CommandTimeout=$timeout 
$dt = New-Object system.Data.datatable 
$da=New-Object System.Data.SQLClient.SQLDataAdapter($cmd) 
[GC]::Collect() 
$start = get-date 
[void]$da.fill($dt) 
$now = get-date 
[int]($now - $start).Milliseconds 
$conn.close() 
#$dt 

Ole-DB : SQL-Client 
538 - 839 
767 - 456 
592 - 678 

因此,對於這種類型的臨時查詢,我更喜歡Ole-DB,因爲我只需調整連接字符串以從Oracle數據庫中提取數據。

+0

*我只需要調整連接字符串以從Oracle數據庫中提取數據*除了那些不支持的不同的OleDB提供商可能會令人驚訝。例如,Oracle的提供商[命令不超時](http://docs.oracle.com/cd/B28359_01/win.111/b28431/appxtype.htm#autoId11) – 2013-04-25 22:49:08