SqlDataReader 与 SqlDataAdapter:返回 DataTable 的性能哪个更好?

Posted

技术标签:

【中文标题】SqlDataReader 与 SqlDataAdapter:返回 DataTable 的性能哪个更好?【英文标题】:SqlDataReader vs SqlDataAdapter: which one has the better performance for returning a DataTable? 【发布时间】:2013-02-06 14:13:57 【问题描述】:

我想知道返回DataTable 时哪个性能更好。这里SqlDataReader 我用DataTable.Load(dr)

使用SqlDataReader

public static DataTable populateUsingDataReader(string myQuery)

    DataTable dt = new DataTable();
    using (SqlConnection con = new SqlConnection(constring))
    
        SqlCommand cmd = new SqlCommand(myQuery, con);
        con.Open();
        SqlDataReader dr = null;
        dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
        if (dr.HasRows)
        
            dt.Load(dr);
        
        return dt;
    

使用SqlDataAdapter:

public DataTable populateUsingDataAdapter(string myQuery)

    SqlDataAdapter dap = new SqlDataAdapter(myQuery,cn);
    DataSet ds = new DataSet();
    dap.Fill(ds);
    return ds.Tables[0];

【问题讨论】:

你为什么不直接注销开始时间循环X次然后注销结束时间 Is datareader quicker than dataset when populating a datatable?的可能重复 @Satinder Singh 与问题无关,但是:在 DataReader 版本中,不要忘记将 SqlCommand 和 DataReader 变量放入 using 块中,因为它们是 IDisposable。 如果你只处理一个表,也许直接调用 DataTable.Load( ) 就足够了。 【参考方案1】:

差异可以忽略不计,因此最好使用更简洁的版本:SqlDataAdapter.Fill

SqlDataReader.Fill在内部创建一个内部类LoadAdapter(派生自DataAdapter),并调用其Fill方法:性能将与SqlDataAdapter.Fill(DataTable)非常相似。

参数的初始化/验证会有一些小的差异,但随着行数的增加,这将变得越来越不重要。

另请注意,您的第二个样本应修改为与第一个样本相当:

public DataTable populateUsingDataAdapter(string myQuery)

    using (SqlConnection con = new SqlConnection(constring))
    
        SqlDataAdapter dap = new SqlDataAdapter(myQuery,con);
        DataTable dt = new DataTable();
        dap.Fill(dt);
        return dt;
    

【讨论】:

+1 - 因为我刚刚写了同样的东西(为了记录,直到我完成后才看到你的答案)。 @joe:谢谢你的回复,如果没有错,那么在这个场景中SqlDataAdapter 将是一个好的选择 @Joe 这里返回的 dt 为空,不是吗? sqlDataReader和sqlDataAdapter的区别真的可以忽略不计吗?您是否有任何显示差异的基准?正如下面所指出的,这个回复fastest-way-to-read-data-from-a-dbdatareader 可能包含一个基准。此外,DataAdapter and DataReader 上的这篇 msdn 文章可能会有用。 我知道这个线程很旧,只是想在解决方案中添加我的一粒沙子:作为一切,我建议测试你的用例,我留下一个 linqpad 脚本来测试,对我来说 DataAdapter 更好因为它允许您将主键映射到 DataTable。 Download LinqPad Script【参考方案2】:

This question,更具体地说,this answer 建议您的第二个示例更快。这当然不是一个详尽的基准测试,但它是一个有趣的测试。

反映DataTable的源码可知,调用DataTable.Load()实际上是创建了一个内部的DataAdapter子类,名为LoadAdapter,并调用了DataAdapterFill()方法。 SqlDataAdapter 在同一个地方完成大部分加载工作。

更重要的是,为了便于阅读,我倾向于第二个示例。这两个示例都无法与直接使用DataReader 提供的快速访问相比,因此我会选择更简洁的代码。

【讨论】:

【参考方案3】:

SqlDataReader 历来比SqlDataAdapter 快得多。 .NET 4.5 中可能已经进行了改进,但我怀疑它的改进是否足以超过 DataReader 的性能。

【讨论】:

不正确。 直接处理来自SqlDataReader 的数据可能比将整个结果集加载到DataTable 更快。但这是比较苹果和橘子。两者在填充DataTable 时具有相似的性能。 你是对的。我假设使用 Reader 来补充自定义类。不要填写DataTable。如果结果必须是DataTable,那么无论使用适配器还是读取器,性能都会同样差。【参考方案4】:

SqlDataReader 将比 SQlDataAdapter 更快,因为它工作在连接状态,这意味着第一个结果一旦可用就会从查询中返回..

【讨论】:

我也知道这个理论部分。我想知道上面代码中哪个更快 @Satindersingh 抱歉,我以为你在问区别..SqlDatareader 使用起来会更快,因为它在连接状态下工作,这意味着第一个结果一旦可用就会从查询中返回.. “SqlDataReader 将比 SQlDataAdapter 更快,因为它在连接状态下工作” - 这不是真的:在这两种情况下,DataTable 在结果返回给调用者之前已完全填充。【参考方案5】:

除了选择的解决方案,我想补充一点:

使用 DataReader,您无需知道您拥有哪种类型的 DbConnection。

您只需要一个实现 IDbConnection 的实例,您可以使用“connection.CreateCommand”,然后使用“dbCommand.ExecuteReader”,然后使用 dataTable.Load。

但是当您使用 DataAdapter 时,您需要知道使用的是哪个连接(即 oracle、sqlserver 等)

(它与线程启动器无关,但我在寻找此主题时使用 g**gle 登陆这里。)

【讨论】:

这是对乔回答的评论。

以上是关于SqlDataReader 与 SqlDataAdapter:返回 DataTable 的性能哪个更好?的主要内容,如果未能解决你的问题,请参考以下文章

将 SqlTransaction 与 SqlDataReader 一起使用

SqlDataAdapter 与 SqlDataReader

.NET SqlDataReader Item[] 与 GetString(GetOrdinal())?

有没有办法将任务并行库(TPL)与 SQLDataReader 一起使用?

关于SqlDataReader使用的一点疑惑

ado:SqlDataAdapter,dataset 与SqlDataReader的用法一