【问题标题】:What are the pros and cons of OleDB versus SQLClient?OleDB 与 SQLClient 的优缺点是什么?
【发布时间】:2009-01-23 18:18:58
【问题描述】:

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

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

谢谢大家。

【问题讨论】:

    标签: .net sql-server-2005 oledb


    【解决方案1】:

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

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

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

    我确实注意到产生了有意义的差异的是错误消息。我在使用旧的 OleDb 应用程序时遇到了问题,出于绝望我将其切换到 SqlClient。当然,它仍然不起作用,但更好的错误消息提供了足够的新信息,我能够解决问题。

    【讨论】:

    • 现在值得注意的是,鉴于我的前两句话,微软现在正在弃用 Ole 以支持 Odbc
    【解决方案2】:

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

    不要听任何人在不了解他们如何测试 OleDB 以及他们使用什么环境(托管代码与托管代码)的情况下对 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)”。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        这里有一些 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 数据库中提取数据。

        【讨论】:

        • 我只需调整连接字符串即可从 Oracle 数据库中提取数据。 除了不同的 OleDB 提供程序不支持的内容可能会令人惊讶。例如commands don't timeout 与 Oracle 的提供者
        【解决方案5】:

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

        我认为您在使用 OleDb 时没有任何问题,除非您使用 XML 等特殊数据类型,在这种情况下您可能需要更加努力。

        【讨论】:

          猜你喜欢
          • 2016-03-26
          • 1970-01-01
          • 2012-05-12
          • 1970-01-01
          • 2010-10-31
          • 1970-01-01
          • 2011-07-24
          • 2011-06-03
          • 2011-04-02
          相关资源
          最近更新 更多