C#使用多线程或并行执行执行SQL SP
我有一个SQL Server SP,并希望为大约1000万个用户记录集执行该SP,以处理用户信息并更新数据库。目前,一个用户更新数据库需要几毫秒的时间。既然要处理数百万条记录,那么最好的方法是什么 我正在考虑使用多线程或并行foreach从C#应用程序中执行此操作。下面是运行SP的基本代码,如何使用它在多线程模式下运行它以更快地完成处理任务C#使用多线程或并行执行执行SQL SP,c#,sql,.net,sql-server,multithreading,C#,Sql,.net,Sql Server,Multithreading,我有一个SQL Server SP,并希望为大约1000万个用户记录集执行该SP,以处理用户信息并更新数据库。目前,一个用户更新数据库需要几毫秒的时间。既然要处理数百万条记录,那么最好的方法是什么 我正在考虑使用多线程或并行foreach从C#应用程序中执行此操作。下面是运行SP的基本代码,如何使用它在多线程模式下运行它以更快地完成处理任务 string connString = "data source=.\SQLEXPRESS;initial catalog=Test;integrated
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();
如何使用它在多线程模式下运行它以更快地完成处理工作
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()的操作中。用于确保正确地处理了这些内容(如果在关闭连接之前抛出异常,那么现在您将保持连接处于打开状态)
请注意,.NET Framework将尝试找到最佳线程数(不同版本的框架可能最终选择不同的线程数)。NET可能会选择多个线程,这些线程是
- 太低(您无法影响,但可以通过显式创建和管理任务来解决)
- 过高,导致SQL Server执行效率低下(由于IO或锁争用、高CPU等)。在这种情况下,可以使用该属性限制线程数。如果移动到功能或多或少的SQL Server,请不要忘记调整属性
如果您想问,尽可能快/高效地完成1000万“集”记录处理的最佳方法是什么,那么这是一个更复杂的问题。这需要更多的分析。至少需要检查
ETL\u测试中的逻辑和模式(表、索引等)。因此,目前,这里没有足够的信息来提供这些方面有意义的帮助。有几种方法可以加快速度:
在表值参数中传递数据,这样您就可以在一次调用中处理它们,这可能是最好的方法,但它确实需要一些设置,而且如果这是一次性的,就不值得了
因为您只处理一个参数,所以将其转换为逗号分隔的值字符串并传入,这样您就可以在服务器上处理每次调用的几千个参数
在不改变太多代码的情况下,您可以做的最简单的事情就是将其放在事务中,并每数千条记录提交一次记录,或者一次提交所有记录。这样做将使速度提高约100倍
多线程最终会慢很多。实际上,您必须将其更改为逐行。或者此进程已经在逐行执行此操作了?还有一个SP被写入以执行逐行操作,这需要很多时间。@SeanLange:不,不会慢很多。在某种程度上,对SQL Server的多个并发请求加快了总体吞吐量。您试图更新哪些用户信息,如列、数据类型?另外,更新信息来自哪里?需要强调的是,TPL通常会完全偏离IO工作的最佳线程数。随着时间的推移,线程的数量(字面上)将趋于无穷大。这很容易通过睡眠(100)
重现+1因为你这么说了,但我想更强调这一点。@usr:根据我的经验,TPL在选择线程数量方面做得很合理,但并不完美。在做与相关问题相关的工作时,我确实必须明确限制平行度。你能举一个例子说明TPL何时会倾向于大量线程吗?我很想了解这种情况。真糟糕。在所有现实IO场景中都可以无限创建线程。该链接抱怨当工作负载配置文件急剧变化时,core创建新线程的速度太慢。它没有提到会创建任意数量的线程。引用:内存使用与线程数量成正比(此处为731)。
。这两个问题都存在。缓慢增长但无限增长。那幅画太吓人了!线程数随时间的线性增长。在一夜之间推断出这一点。这就是导致生产系统瘫痪的问题。