使用SQL Server数据库调用的C#多线程

使用SQL Server数据库调用的C#多线程,c#,database,multithreading,.net-4.5,C#,Database,Multithreading,.net 4.5,我有一个包含用户详细信息的大型数据表。我需要将用户的详细信息从数据库中的几个表中填写到这个表中。我遍历了表中的每一行,并使用ADO.NET对象和方法对数据库中的不同表进行了多次调用,对结果进行处理和重新组织,并将其发送到主表。这很好,但是要慢下来。。。 我的想法是将大表拆分为几个小表,同时在几个线程中运行completedAddressDetails方法,最后将小表合并为一个结果表。我已经使用TPL的任务对象实现了这个想法。下面有一个代码。它工作正常,但执行时间没有任何改善。 几个问题: 1.为

我有一个包含用户详细信息的大型数据表。我需要将用户的详细信息从数据库中的几个表中填写到这个表中。我遍历了表中的每一行,并使用ADO.NET对象和方法对数据库中的不同表进行了多次调用,对结果进行处理和重新组织,并将其发送到主表。这很好,但是要慢下来。。。 我的想法是将大表拆分为几个小表,同时在几个线程中运行completedAddressDetails方法,最后将小表合并为一个结果表。我已经使用TPL的任务对象实现了这个想法。下面有一个代码。它工作正常,但执行时间没有任何改善。 几个问题: 1.为什么执行时间没有任何改进? 2.我必须做些什么才能改进它

谢谢你的建议

        resultTable1 = data.Clone();
        resultTable2 = data.Clone();
        resultTable3 = data.Clone();
        resultTable4 = data.Clone();
        resultTable5 = data.Clone();

        DataTable[] tables = new DataTable[] { resultTable1, resultTable2, resultTable3, resultTable4, resultTable5 };

        for (int i = 0; i < data.Rows.Count; i += 5)
        {
            for (int j = 0; j < 5; j++)
            {
                if (data.Rows.Count > i + j)
                {
                    tables[j].Rows.Add(data.Rows[i + j].ItemArray);
                }
            }

        }



Task[] taskArray = {Task.Factory.StartNew(() =>CompleteAddressDetails(resultTable1)),
                               Task.Factory.StartNew(() =>CompleteAddressDetails(resultTable2)),
                               Task.Factory.StartNew(() =>CompleteAddressDetails(resultTable3)),
                               Task.Factory.StartNew(() =>CompleteAddressDetails(resultTable4)),
                               Task.Factory.StartNew(() =>CompleteAddressDetails(resultTable5))};

            Task.WaitAll(taskArray);
resultable1=data.Clone();
resultTable2=data.Clone();
resultTable3=data.Clone();
resultTable4=data.Clone();
resultTable5=data.Clone();
DataTable[]tables=新的DataTable[]{resultTable1,resultTable2,resultTable3,resultTable4,resultTable5};
对于(int i=0;ii+j)
{
表[j].Rows.Add(数据.Rows[i+j].ItemArray);
}
}
}
Task[]taskArray={Task.Factory.StartNew(()=>CompleteAddressDetails(Resultable1)),
Task.Factory.StartNew(()=>completedAddressDetails(resultable2)),
Task.Factory.StartNew(()=>completedAddressDetails(resultable3)),
Task.Factory.StartNew(()=>completedAddressDetails(resultable4)),
Task.Factory.StartNew(()=>completedAddressDetails(resultable5));
Task.WaitAll(taskArray);

没有任何改进,因为您无法编码sql server数据库如何处理您的呼叫


我建议在SQL Server上使用用户定义的表类型,这是一个接受此表类型的存储过程,然后将您拥有的数据表发送到存储过程并在其中进行处理。然后,您就可以继续从那里进行优化。

当使用多线程并行而没有任何性能优势时,基本上有两种可能性:

  • 代码不受CPU限制,因此在任务上投入更多CPU不会有帮助
  • 代码使用了太多的同步,实际上不允许实际的并行执行
  • 在这种情况下,1可能是原因。您的代码没有完成足够的CPU工作,无法从多线程中获益。很可能,您只是在等待数据库完成工作

    如果不了解
    completedaddressdetails
    方法的作用,很难给出任何指针-我假设它逐个遍历所有行,并执行两个单独的查询来填充细节。即使每个查询都足够快,但无论您做什么,执行数千个单独的查询都会损害您的性能,尤其是当这些查询需要锁定数据库中的某些共享状态时


    首先,想一个更好的方法来填充细节。也许您可以将其中一些查询连接在一起,或者甚至可以一次加载所有行。第二,尝试分析服务器上发生的实际查询。了解您是否可以通过添加一些索引或更好地使用现有索引来提高它们的性能。

    使用
    Task.Factory.StartNew运行这些方法并不是最好的方法。最好将
    completedAddressDetails
    方法重写为(
    async/await
    )。鉴于您提供的详细程度,不可能说出您的瓶颈所在。当您直接将查询运行到数据库中时,查询的执行速度有多快?你确定你已经涵盖了表上索引的所有内容,你的查询将从中受益吗?你完全正确,我一行一行地运行,并根据结果处理3-5个对DB的非常简单的调用。您认为,如果我先将这些表中的数据加载到DataTable对象中,然后在单独的线程中使用linq查询它们,这种方式是否有助于提高时间?@LevZ客户端根本没有理由使用多线程—所有的工作都是在网络和数据库引擎中完成的。试着找到一种减少查询数量的方法——对于一个典型的操作,每个操作应该只有几个查询(我们说的是个位数)。例如,您可以一次向查询传递多个ID(例如,使用表值参数),然后手动更新数据表中的相关行。但我真的不能说太多具体的东西,只有一般的指示。