18

一些上下文:我正在开发的系统之一是 .net 2.0 Web 应用程序。VB.net 用于前端,SQL Server 2005 用于后端。由于各种已被时间遗忘的原因,最初的设计者决定使用 .Net OleDB 连接而不是 SQLClient 连接。

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

谢谢大家。

4

5 回答 5

23

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

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

以我个人的经验,我从未注意到速度差异;我也找不到任何东西来支持这个说法。我怀疑性能优势是真实存在的,但是您必须处理数百万条记录才能开始衡量它。

我确实注意到了一个有意义的区别是错误消息。我在使用旧的 OleDb 应用程序时遇到了问题,我绝望地将其切换到 SqlClient。当然,它仍然没有用,但是更好的错误消息提供了足够的新信息,我能够解决这个问题。

于 2009-01-23T18:26:15.483 回答
13

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

不要听任何人在不了解他们如何测试它以及他们使用什么环境(托管代码与托管代码)的情况下对 OleDB 的性能进行虚假指控。唯一让 OleDB 变慢的是需要大量的管道才能使本机代码与托管代码配合得很好。还要记住,SqlClient .NET 库有它自己的管道,它不像大多数人认为的那样是一个 NATIVE .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 Native Client Programming\SQL Server 2008 Native Client (OLE DB)”。

于 2010-07-01T03:59:47.460 回答
3

我和 Joel 一起讨论这个问题,如果您打算坚持使用 SQL Server,SqlClient 是最好的选择。有性能提升,但您必须开始使用大型集合和大量事务才能开始看到这样做的好处。

总体而言,所提供的错误和功能更适合 SQL Server 的功能,因此如果您愿意,这是一个“更好”的实现。它还支持 MARS,这对某些人来说是“必须做的”开关。

于 2009-01-23T18:30:10.733 回答
3

下面是一些PowerShell代码进行直接比较:

奥莱数据库:

$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

SQL客户端:

$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 数据库中提取数据。

于 2011-02-12T19:15:41.667 回答
2

您始终可以使用 SqlClient 和 OleDB 编写包含一些典型操作的示例应用程序,并对它们进行基准测试以比较性能。我怀疑差异会很大,但只有一种方法可以找出答案。

我认为您在使用 OleDb 时不会有任何问题,除非您使用像 XML 这样的外来数据类型,在这种情况下您可能需要更加努力地工作。

于 2009-01-23T18:37:18.050 回答