【问题标题】:.NET - Begin reading from DataReader before query is complete?.NET - 在查询完成之前开始从 DataReader 读取?
【发布时间】:2011-01-12 23:34:36
【问题描述】:

我目前正在开发一个将旧数据库转换为新样式的程序,我被分配的任务之一是删除一些旧的二进制列并将它们转换为我们存储库中的文档。

我们的表中有大约 110 万行,我的过程大约需要 12 小时才能完成。

我正在寻找使这一切变得更快的方法,而我正在研究的一件事是更快地获取数据。如果有办法在查询完成之前获得查询结果?我注意到,当我在查询分析器中对该表运行“select *”语句时,我会立即开始返回结果,但是当我在 .NET 中使用 ExecuteReader 时,该查询似乎需要大约 30 分钟才能开始读取行.

【问题讨论】:

  • 您的实际代码是什么样的?听起来您在非索引列上有一些繁重的 where 查询。在不过滤数百万列的情况下执行普通 SELECT 应该很快,ExecuteReader 也是如此。
  • 也许您可以尝试将您的查询分解成较少的行数并运行几个线程来处理它们?
  • @Pauli - 问题不在于索引,而在于数据量。我正在处理几个 BLOB 列。 :(

标签: .net datareader


【解决方案1】:

使用command.ExecuteReader(CommandBehavior.SequentialAccess) 可能会有所帮助。但是,这样做需要您按顺序读取列,并且需要您以不同的方式读取二进制值。我推荐reading the documentation on SequentialAccess,这样您就知道可能需要对您的代码进行哪些其他更改。

假设同一查询在查询分析器中立即运行。这告诉我,查询本身并不需要 30 分钟才能返回第一个结果,或者它会在查询分析器中这样做。我认为对大二进制值的处理可能是对这种差异的解释。一种快速的测试方法是更改​​查询以选择除二进制列之外的所有内容,并查看这是否会更改 ExecuteReader 花费的时间。如果没有二进制列的执行时间相同,那么 SequentialAccess 不太可能有帮助。如果没有二进制列会更快,那么 SequentialAccess 可能值得使用。

【讨论】:

  • 澄清一下,QA 中查询的全部返回仍然需要 30 分钟,它只是立即开始返回部分数据。我设法通过使用 SqlCommand.BeginExecuteReader 在我的代码中复制效果,并且显着提高了性能。接下来我会试试这个建议,看看我能把总时间降到多少。
  • 我的大部分性能提升来自使用 SqlCommand.BeginExecuteReader,但这也产生了很好的影响。总时间从 12 小时减少到 1.5 小时。
【解决方案2】:

如果您不需要查询中的所有列,建议不要使用 select *。也许这个问题也会有所帮助:Performance optimization strategies of last resort

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多