BackGround:我正在执行大约80个线程,每个线程将不断向数据库添加数据(每个线程大约30k次)(我正在使用sql server express)。但程序的缓慢部分是TableAdapter.Update部分。
为什么我问这个问题:要知道更新数据库的更快方法。
我在想:是为每个线程分配一个新的压缩数据库,每10k个条目与实际数据库同步后。(但我不知道如何做任何部分)
破碎到骨干代码:
class Do : Form1
{
public int i;
public void FillTable(string[] ws)
{
DataRow row = database1DataSet1.Result.NewResultRow();
row["one"] = ws[0];
try
{
database1DataSet1.Result.Rows.Add(row);
}
catch {}
lock (this)
{
try { resultTableAdapter.Update(database1DataSet1.Result); }
catch { }
}
}
public void start()
{
for (;;) //Run about 30k to 40k times
{
string[] ws = SOMEFUNC();
FillTable(ws);
}
}
}
致电代码:
Do[] case1 = new Do[80];
Thread[] t = new Thread[80];
for (int ij = 0; ij < 80; ij++)
{
case1[ij] = new Do();
case1[ij].i = ij;
t[ij] = new Thread(new ThreadStart(case1[ij].start));
t[ij].Start();
}
有什么想法吗?
编辑:其中一个解决方案:http://www.dotnetcurry.com/ShowArticle.aspx?ID=323
答案 0 :(得分:2)
你可以做多件事。
您可以通过SqlBulkCopy进行批量加载,或者(因为您在SqlServer 2008上)可以将表传递给存储过程并让存储过程使用MERGE INTO sql命令来快速插入或更新表。
我们可以使用这种方法在10秒内获得大约200k的插入。
答案 1 :(得分:1)
您可以使用Dapper代替TableAdapter。它将消除大部分开销。
特别是你可以使用一个可枚举的助手:
// begin tran
var items = new[] {{a=1,b=2},{a=2,b=3}};
cnn.Execute("insert table(a,b) values(@a,@b)", items);
// commit tran
Dapper会很快,但SqlBulkCopy会更快 ,因为它专为此特定问题而设计。
答案 2 :(得分:0)
老实说,我会赞成80个线程,从1或2开始,给他们更多的工作,并做一些性能和负载测试,看看他们能做多少,以及多快。这将让你真正了解他们在x时间内可以做多少,以确定你是否真的需要更多线程。如果确实需要更多线程,请逐步执行。 2,3,4 .. 80线程?这对我来说似乎很疯狂,因为我没有一个进程(除了核心系统进程之外)甚至可以达到接近80个线程,包括SQL Server Enterprise R2和其他东西..如果你使用80个线程的原因是“不大”理由“,那么你应该重新考虑一下。不要忘记,由于带宽,延迟和其他与网络相关的问题,您仍然存在性能限制。在谈论表演和可能导致其放慢速度的事情时,请考虑“剩下的是什么?”。
增量性能测试是我对此的建议。甚至可能对您正在使用的对象进行研究,因为它们可能是昂贵的对象,并且可能会研究一些替代方法来推动您的数据。