Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有一种多线程处理SqlDataReader的方法?_Sql_Sql Server_Performance_Multithreading_C# 3.0 - Fatal编程技术网

有没有一种多线程处理SqlDataReader的方法?

有没有一种多线程处理SqlDataReader的方法?,sql,sql-server,performance,multithreading,c#-3.0,Sql,Sql Server,Performance,Multithreading,C# 3.0,我有一个Sql查询,返回超过50万行要处理。。。这个过程不会花费很长时间,但是我想通过一些多处理来加快它。考虑到下面的代码,是否可以轻松地执行类似的多线程操作 using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { // ...process row } } 如果我能在结果列表的开头和中间得到一个光标,那就太完美了。这样,我就可以有两个线程来处理这些

我有一个Sql查询,返回超过50万行要处理。。。这个过程不会花费很长时间,但是我想通过一些多处理来加快它。考虑到下面的代码,是否可以轻松地执行类似的多线程操作

using (SqlDataReader reader = command.ExecuteReader())
{
    while (reader.Read())
    {
        // ...process row
    }
}
如果我能在结果列表的开头和中间得到一个光标,那就太完美了。这样,我就可以有两个线程来处理这些记录。但是SqlDataReader不允许我这样做


你知道我如何做到这一点吗?

设置生产者/消费者队列,其中一个生产者进程可以从读卡器中提取,并尽可能快地将记录排队,但不进行“处理”。然后是一些其他数量的进程(需要多少进程取决于您的系统)来退出队列并处理每个排队的记录。

这是一个简单的范围查询,比如WHERE Id介于1和500000之间吗?如果是这样,您可以启动N个查询,每个查询返回范围的1/N。但它有助于了解单线程方法的瓶颈所在。如果要从一个磁盘轴执行连续读取以完成查询,则可能需要使用单个线程。如果它是按一定范围跨轴分区的,那么您可以智能地调整查询以最大限度地提高磁盘吞吐量(即,通过单独的查询并行读取每个磁盘)。如果您希望所有的行都在内存中,那么您可以随意进行并行化。但是如果查询更复杂,那么您可能无法轻松地对其进行分区,而不会产生大量开销。大多数情况下,上述选项不会很好地应用,Joel提到的生产者/消费者将是唯一可以并行化的地方。根据您处理每一行所花费的时间,这可能只会带来微不足道的收益。

您不应该在客户端上读取那么多行

也就是说,您可以将查询划分为多个查询并并行执行它们。这意味着在不同的线程中启动多个SQLCommand,并让它们各自搅动结果的一个分区。A+问题是如何划分结果,这在很大程度上取决于您的数据和查询:

  • 您可以使用一系列键(例如,
    ID介于1和10000之间,
    ID介于10001和20000之间等)
  • 您可以使用属性(例如,(1,2)中的
    RecordTypeID
    ,(3,4)中的
    RecordTypeID
    等)
  • 您可以使用合成范围(即1到1000之间的
    行数()等),但这很难向右拉
  • 您可以使用散列(例如,
    BINARY\u校验和(*)%10==0
    BINARY\u校验和(*)%10==1
    等)

  • 您只需非常小心,分区查询在执行过程中不会重叠和阻塞(即扫描相同的记录并获取X锁),从而相互序列化。

    如果您知道如何对查询进行分区,您可以并行运行两个查询。您好,您找到了解决方案吗?嗯。。奇怪,但我找不到已经实现的通用生产者/消费者模式。现在就玩我自己的游戏,但这里的输入是值得赞赏的:你是否最终编码了你自己的生产者/消费者,如果是的话,你能分享它吗?我认为这不是一个很好的主意-开发者不应该对数据了解这么多(或者它在未来会是什么样子)。此外,任何解决方案都应该在其他场景中可重用。像上面提到的生产者/消费者一样,一个真正的多线程解决方案是最好的。