【问题标题】:SqlDataReader are these two the same Which one is fasterSqlDataReader 这两个是一样的 哪个更快
【发布时间】:2011-10-20 05:34:41
【问题描述】:

我正在使用 SqlXml 和返回 xml 而不是原始数据的存储过程。返回时如何实际读取数据是一个xml并且不知道列名。我使用了以下版本,听说通过序数从 SqlDataReader 获取数据比通过列名更快。请建议哪个是最好的,并有正当的理由或证明

  1. sqlDataReaderInstance.GetString(0);

  2. sqlDataReaderInstance[0];

【问题讨论】:

标签: c# sql ado.net sqldatareader sqlxml


【解决方案1】:

听说通过序数从 SqlDataReader 获取数据比通过列名更快

您的两个示例都是通过索引(序数)而不是列名获取数据:

通过列名获取数据:

while(reader.Read())
{
    ...
    var value = reader["MyColumnName"];
    ...
}

可能比通过索引获取数据要慢:

int myColumnIndex = reader.GetOrdinal("MyColumnName");
while(reader.Read())
{
    ...
    var value = reader[myColumnIndex];
    ...
}

因为第一个示例必须反复查找“MyColumnName”对应的索引。如果行数非常多,则差异甚至可能很明显。

在大多数情况下,差异不会很明显,因此请注意可读性。

更新

如果您真的关心性能,使用序数的替代方法是使用DbEnumerator 类,如下所示:

foreach(IDataRecord record in new DbEnumerator(reader))
{
    ...
    var value = record["MyColumnName"];
    ...
}

DbEnumerator 类会读取一次架构,并维护一个将列名映射到序数的内部 HashTable,这可以提高性能。

【讨论】:

  • Joe,我相信所有主要的 ADO.NET 连接器都为列名到序号映射维护了一个内部哈希表。我已经确认了 SQLite 和 MySQL。所以"record["string"]" 无论如何都是相当有效的(我的意思是即使没有 DbEnumerator 类)。但我确实认为,像你一样为读者服务确实有其好处。
  • 使用更新的解决方案,我收到以下错误:foreach 语句无法对System.Data.Common.DbEnumerator' because it does not contain a definition for GetEnumerator' 类型的变量进行操作或无法访问
【解决方案2】:

与从磁盘获取数据的速度相比,两者实际上都一样快。

这两个调用是不等价的:带有索引器的版本返回一个对象,而GetString() 将对象转换为字符串,如果不可能,则抛出异常(即列是DBNull)。

因此,尽管GetString() 可能会稍微慢一些,但在您使用它时无论如何都会转换为字符串。

鉴于以上所有我会使用GetString()

【讨论】:

  • +1 @Jeremy 如果您提供某种个人资料,证明,我会标记此答案
【解决方案3】:

Indexer 方法更快,因为它返回 native format 中的数据并使用序数。

看看这些线程:

  1. Maximize Performance with SqlDataReader
  2. .NET SqlDataReader Item[] vs. GetString(GetOrdinal())?

【讨论】:

  • 这是否意味着我也可以instance.Item[0]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多