OleDB与SQLClient的优缺点是什么?

时间:2009-01-23 18:18:58

标签: .net sql-server-2005 oledb

某些上下文:我正在研究的系统之一是.net 2.0 Web应用程序。用于前端的VB.net和用于后端的SQL Server 2005。出于各种原因,原设计师决定使用.Net OleDB连接而不是SQLClient连接。

经过几年的发展,这个特殊的系统正处于从“beta”到“1.0”状态的过程中。我们此时讨论的一件事就是转向SQLClient连接。虽然我知道最好的做法是使用它,并且这是获得SQL Server 2005(我们没有使用,显然)的更好的功能的唯一方法,使用这个功能的优势是什么?其他?我应该知道的任何隐藏的陷阱?还有人能指出一些显示相对速度的基准吗? (我听说SQLClient应该更快,但我从未见过任何数字来支持它。)

谢谢,所有。

5 个答案:

答案 0 :(得分:19)

OleDb更通用。如果您将来移动到不同的数据库类型,那么它很可能会有一个Ole驱动程序,您不必更改代码。

另一方面,如你所说,Sql Server本机驱动程序应该更快,并且它具有更好的参数支持(参数可以使用名称,而不是 按顺序)

根据我的个人经验,我从未注意到速度差异;我也找不到任何支持索赔的东西。我怀疑性能优势是真实的,但在开始测量之前你必须处理数百万条记录。

我所注意到的是错误消息的有意义的区别。我在使用旧的OleDb应用程序时遇到了麻烦,我出于绝望而将其切换为SqlClient。当然,它仍然无效,但更好的错误消息提供了足够的新信息,我能够解决问题。

答案 1 :(得分:12)

OLEDB比SQLClient快得多,在通过ADO.NET访问时除外。 OLEDB的驱动程序是用本机非托管代码编写的,但是当您通过ADO.NET访问这些驱动程序时,您必须经历多个层(包括抽象层和COM互操作层)。抽象层负责资源管理,例如管理内存句柄以确保正确进行垃圾收集,将数据类型和参数更改为.NET类型以及将oledb缓冲区转换为行和列绑定。 COM互操作层负责编组从.NET传递消息到COM,反之亦然,包括锁定/解锁/转换指针。

如果没有理解他们如何测试OleDB的性能以及他们使用的环境(托管代码与托管代码),请不要聆听任何对OleDB性能进行错误指责的人。减少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)进行交流。请记住,Microsoft正在更新OleDB和ODBC,并且最新的OleDB驱动程序可以与最新的非托管本机SQL客户端库进行通信。 Microsoft建议在需要高性能时在非托管应用程序中使用OleDB。

有关详细信息,请参阅“SQL Server 2008联机丛书\数据库引擎\开发人员指南\ SQL Server 2008本机客户端编程\ SQL Server 2008本机客户端(OLE DB)”。

答案 2 :(得分:3)

我和Joel在一起,如果你打算坚持使用SQL Server,最好使用SqlClient。有性能提升,但你必须开始使用大型集合,并且大量的事务通常会开始看到它的好处。

总的来说,提供的错误和功能更适合SQL Server可以执行的操作,因此如果您愿意,可以使用“更好”的实现。它也支持MARS,有些人认为它是“必须做”的转换。

答案 3 :(得分: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数据库中提取数据。

答案 4 :(得分:2)

您总是可以使用SqlClient和OleDB编写一个带有一些典型操作的示例应用程序,并对它们进行基准测试以比较性能。我怀疑差异是否显着,但只有一种方法可以找到答案。

我认为使用OleDb没有任何问题,除非你使用像XML这样的奇特数据类型,在这种情况下你可能需要更努力地工作。