C#使用多线程或并行执行执行SQL SP

时间:2016-02-17 21:52:04

标签: c# sql .net sql-server multithreading

我有一个SQL Server SP,并希望为大约1000万个用户记录集执行该操作,以处理用户信息和更新数据库。目前,1个用户需要几毫秒来更新数据库。既然,它必须处理数百万条记录,最好的方法是什么?

我正在考虑使用多线程或并行foreach从C#应用程序中执行此操作。下面是运行SP的基本代码,我如何使用它在多线程模式下运行它来更快地完成处理工作?

 string connString = "data source=.\SQLEXPRESS;initial catalog=Test;integrated security=True;";
            SqlConnection conn = new SqlConnection(connString);
            conn.Open();
            SqlCommand cmd = new SqlCommand("ETL_TEST", conn);
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add(new SqlParameter("@user_id", '12345'));
            cmd.ExecuteReader();
            conn.Close();

3 个答案:

答案 0 :(得分:3)

  

如何使用它在多线程模式下运行它来更快地完成处理工作?

Parallel.ForEach()是实现目标的一个非常合理的起点。 Up to a point,向SQL Server发送并发请求可以提高整体吞吐量。

将代码放入Parallel.ForEach()的操作中。使用using statements确保正确处理事物(如果在关闭之前抛出异常,您将立即打开连接。)

请注意,.NET Framework将尝试查找最佳线程数(并且框架的不同版本可能最终选择不同的数字)。 .NET可能会选择多个

的线程
  • 太低(你无法影响,但你可以通过明确地创建和管理任务来解决)
  • 太高,导致SQL Server执行效率低下(由于IO或锁争用,高CPU等)。在这种情况下,您可以使用MaxDegreeOfParallelism属性来限制线程数。如果转移到功能更强大或更不强大的SQL Server,请不要忘记调整属性。

请注意,多线程解决方案虽然可能比单线程解决方案更有效,但仍然非常繁琐。它向数据库请求每个用户记录。在这种情况下,我通过将一批工作发送到SQL Server而不是单个工作项来实现数量级的性能改进。通过重新设计存储过程以同时接受多个用户,您可能会看到最大的收益。

答案 1 :(得分:0)

  

因为它必须处理数百万条记录,最好的方法是什么?

如果你问的是使这个过程并行的最佳方法是什么,那么@ Eric的答案看起来很有希望。我同意一般来说,“在某种程度上,向SQL Server发送并发请求可以提高整体吞吐量。”,只要我们真的强调“达到某一点”的一部分。但“那一点”很容易就是一次只能运行一些(取决于逻辑和架构),这不是你正在寻找的增益类型。

如果你问的是尽可能快速/有效地完成1000万“记录集”处理的最佳方法,那么这是一个更为复杂的问题。它需要更多的分析。至少,它需要检查ETL_TEST存储过程中的逻辑和您的架构(表,索引等)。所以目前没有足够的信息来提供这些方面的任何有意义的帮助。

答案 2 :(得分:0)

有几种方法可以加快速度:

  1. 将数据传递给一个table-value参数,这样你可以在一次调用中处理它们可能是最好的方法,但它确实需要一些设置,如果这是一次性的事情,不值得,IMO
  2. 由于您正在处理单个参数,因此将其转换为以逗号分隔的值字符串并将其传入,以便您可以在服务器上每次调用处理几千个。
  3. 在不更改代码的情况下,您可以做的最简单的事情就是将其放入一个事务中并每隔几千条记录提交您的记录,或者同时提交所有记录。这样做可以将速度提高约100倍。