如何在C#中并行执行SQL查询?
问题描述:
我有3个SQL查询按照下面的方式运行,目前我正在按顺序运行它们中的每一个,我希望探索在C#中并行运行它们的选项。我想知道C#有没有这种可能性?它甚至可以做到吗?如何在C#中并行执行SQL查询?
sql1 = select DISTINCT A.Name
from masterdata.Areas as A,
...................
and SPB.SoftwareProductBuild = 'build1'
sql1 = select DISTINCT A.Name
from masterdata.Areas as A,
...................
and SPB.SoftwareProductBuild = 'build2'
sql1 = select DISTINCT A.Name
from masterdata.Areas as A,
...................
and SPB.SoftwareProductBuild = 'build3'
SqlCommand cmd = new SqlCommand(sql1, odsConn);
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Read();
if (rdr.HasRows)
{
}
SqlCommand cmd = new SqlCommand(sql2, odsConn);
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Read();
if (rdr.HasRows)
{
}
SqlCommand cmd = new SqlCommand(sql3, odsConn);
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Read();
if (rdr.HasRows)
{
}
答
我会先修改你的代码,这样它就会调用ThreadPool
线程,使用Task
,这是不是最好的方式,但仍然会让它parallel
,那么我会建议一个更好的机制,使用Dapper Micro ORM
,这使其处理起来非常简单。什么我做的是包装您的查询在不同的任务,在他们每个人的调用一个单独的线程,需要单独的连接对象,将在并行
Task t1 = Task.Run(() => {
SqlCommand cmd1 = new SqlCommand(sql1, odsConn1);
SqlDataReader rdr1 = cmd1.ExecuteReader();
rdr1.Read();
if (rdr1.HasRows)
{
}
});
Task t2 = Task.Run(() => {
SqlCommand cmd2 = new SqlCommand(sql2, odsConn2);
SqlDataReader rdr2 = cmd2.ExecuteReader();
rdr2.Read();
if (rdr2.HasRows)
{
}
});
Task t3 = Task.Run(() => {
SqlCommand cmd3 = new SqlCommand(sql3, odsConn3);
SqlDataReader rdr3 = cmd3.ExecuteReader();
rdr3.Read();
if (rdr3.HasRows)
{
}
});
执行现在,您可以等待任务为完成:
在同步方法:
Task.WaitAll(t1,t2,t3);
在一个异步方法:,要声明async
await Task.WhenAll(t1,t2,t3);
要点需要方法:
- 这是不换行IO /远程调用的任务,因为它会调用一个线程池线程,一个好的做法只需发送一个电话并等待。
- 更好的机制是使用固有的
Async APIs
像DbDataReader
和DbConnection
有异步API。因为这需要在后台进行处理,因此不使用像Thread
这样的资源。 - 注意我用的每个查询一个单独的Connection对象,因为这不是线程安全的,安全的将需要异步API的,在平行
更好的方式来执行它们:
使用像Dapper这样的Micro ORM,在扩展IDbConnection
方面做得非常好,并公开了异步API,如QueryAsync
,它将返回结果Task<IEnumerable<T>>
,虽然它需要整个链标记为async
,并且需要单独的Connection
,但可以有效地处理多个电话高效。与SqlClient不同,它节省了创建IEnumerable的努力,从DataReader or Dataset
答
将它作为UNION
或WHERE SPB.SoftwareProductBuild IN ('build1', 'build2','build3')
并让数据库对它进行排序。
更有效地利用连接,网络,脑力和CPU。
使用线程也许 – GurV
使用异步等待,这是唯一的和最好的解决方案 –
据我所知,并行查询依赖于数据库服务器。即使您的应用程序同时向数据库服务器发送查询,也会决定如何执行它们。 – afaolek