我有一个C#应用程序,它将行插入SQL Server数据库中的三个单独的表中。这是一个庞大的批量工作(每个2 - 3M +行)。我的代码看起来像这样(我编辑了以获取不必要的细节):
string sqlCust = "INSERT INTO customer (account, name, last_order) VALUES (@account, @name, @last_order)";
string sqlOrder = "INSERT INTO orders (num, order_date) VALUES (@num, @order_date)"
string sqlOrderLines = "INSERT INTO order_lines (product) VALUES (@prod)"
db.Open();
while (GetNextCust())
{
using (SqlCommand cmdIns = new SqlCommand(sqlCust, db.Connection))
{
cmdIns.Parameters.Add("@account", custAcc);
cmdIns.Parameters.Add("@name", custName);
cmdIns.Parameters.Add("@last_order", lastOrder);
cmdIns.ExecuteNonQuery();
}
while (GetNextOrder(custAcc))
{
...
while (GetNextOrderLine(orderNum)
{
...
}
}
}
该过程处于脱机状态,我希望尽可能多地使用数据库排队以提高吞吐量。我的问题是,是否有一个最佳线程数(或者有没有办法发现这可能是什么 - 除了试验和错误)?此外,在使用线程做这样的事情时,是否需要警惕?
答案 0 :(得分:0)
除非您正在进行大量处理,否则我猜测您的瓶颈将是磁盘本身(数据库)。因此,最佳线程数可能是一个。
当然,您必须与希望退出应用程序的人进行交易,而这可能正在运行(如果它是应用程序),因此您需要某种退出检查以及时关闭。
答案 1 :(得分:0)
Muli线程应用程序只能在多核计算机上处理得更快。
如果数据库是瓶颈,它可能是,那么添加线程会减慢进程的速度,因为除了线程之间的任务切换开销之外,数据库将花费更多时间排队和管理工作。多个请求。
答案 2 :(得分:0)
好吧,我认为你可以尝试某种连接池,这种方式对于每个新用户(调用一些数据库事务)你会获得一个新线程(我称之为DBBrockers),这将使他能够访问数据库。为了实现这一切,您将需要一台多核机器;更多处理器,更多线程通过。
答案 3 :(得分:0)
你需要做实验。如果您正在读取和写入单个源,那么最佳线程数可能是一个。如果您正在阅读多个来源并写入单一来源,那么2或3可能会获得一些改进。
在上面的案例中,最重要的胜利是从事务性插入切换到SqkBulkCopy
。
答案 4 :(得分:0)
不幸的是,反复试验是您的最佳选择。事先很难预测确切的最佳设计,因为这里有许多因素需要考虑。 UPDATE的数据来自哪里?如果它们来自共享资源,那么多线程可能无助于此。此外,桌子的设计也起到了作用。 SQL Server是一个复杂的数据库,这个批量更新不一定是I / O绑定的。网络通信也可以在这里发挥作用,SQL Server配置也是如此。
对于最佳线程数,此处再次尝试和错误。我从两个开始,然后尝试将该数字提高,甚至超过你拥有的核心数量。原因是因为您的客户端和服务器之间可能有一个网络。此外,每个线程应保持自己的数据库连接。
作为客户端处理的替代方法,您可以使用WCF将整个批处理作业输入文件(或您拥有的任何内容)上载到服务器。然后,您可以使用更好的机制来执行批量更新,而不是使用单个SQL命令。
始终“测试和测量”。