C# 使用多线程或并行执行执行 SQL SP
本文关键字:执行 SQL SP 并行执行 多线程 | 更新日期: 2023-09-27 18:35:03
我有一个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();
如何使用它在多线程模式下运行它以更快地完成处理工作?
Parallel.ForEach(( 是实现目标的一个非常合理的起点。 在某种程度上,向 SQL Server 发送并发请求可以提高整体吞吐量。
将代码放入 Parallel.ForEach(( 的操作中。使用 using 语句来确保正确处理内容(现在,如果在关闭连接之前抛出异常,您将保持连接打开状态(。
请注意,.NET Framework 将尝试查找最佳线程数(不同版本的框架最终可能会选择不同的线程数(。.NET 可能会选择多个线程,这些线程是
- 太低(您无法影响,但您可以通过显式创建和管理任务来解决(
- 太高,导致 SQL Server 中的执行效率低下(由于 IO 或锁争用、高 CPU 等(。在这种情况下,可以使用 MaxDegreeOfParallelism 属性来限制线程数。如果移动到功能更强大的 SQL Server,请不要忘记调整属性。
虽然可能比单线程解决方案更有效,但仍然非常健谈。它向数据库发出每个用户记录的请求。在这种情况下,我通过将一批工作发送到 SQL Server 而不是单个工作项实现了数量级的性能改进。通过重新设计存储过程以同时接受多个用户,您可能会看到最大的收益。
既然它必须处理数百万条记录,那么最好的方法是什么?
如果你问的是使过程并行的最佳方式是什么,那么@Eric的答案看起来很有希望。我同意一般来说,"在一定程度上,向SQL Server发送并发请求可以提高整体吞吐量",只要我们真正强调"在一定程度上"部分。但是"那个点"很容易一次运行几个(取决于逻辑和模式(,这不是您正在寻找的增益类型。
如果您问尽可能快速/高效地处理 1000 万"组"记录的最佳方法是什么,那么这是一个更复杂的问题。它需要更多的分析。至少需要检查ETL_TEST
存储过程和架构(表、索引等(中的逻辑。因此,就目前而言,这里提供的信息不足以提供任何有意义的帮助。
有几种方法可以加快速度:
- 在表值参数中传递数据以便您可以在一次调用中处理它们可能是最好的方法,但它确实需要一些设置,如果这是一次性的事情,那么真的不值得,IMO。
- 由于您正在处理单个参数,因此请将其转换为逗号分隔的值字符串并将其传入,以便您可以在服务器上处理每个调用的几千个。
- 在不更改太多代码的情况下,您可以做的最简单的事情是将其放入事务中,并每隔几千条记录提交一次提交记录,或者一次提交所有记录。这样做将使速度提高约 100 倍。