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
,并调用了DataAdapter
的Fill()
方法。 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())?