如何在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) 
{ 
} 
+0

使用线程也许 – GurV

+0

使用异步等待,这是唯一的和最好的解决方案 –

+0

据我所知,并行查询依赖于数据库服务器。即使您的应用程序同时向数据库服务器发送查询,也会决定如何执行它们。 – afaolek

我会先修改你的代码,这样它就会调用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); 

要点需要方法:

  1. 这是不换行IO /远程调用的任务,因为它会调用一个线程池线程,一个好的做法只需发送一个电话并等待。
  2. 更好的机制是使用固有的Async APIsDbDataReaderDbConnection有异步API。因为这需要在后台进行处理,因此不使用像Thread这样的资源。
  3. 注意我用的每个查询一个单独的Connection对象,因为这不是线程安全的,安全的将需要异步API的,在平行

更好的方式来执行它们:

使用像Dapper这样的Micro ORM,在扩展IDbConnection方面做得非常好,并公开了异步API,如QueryAsync,它将返回结果Task<IEnumerable<T>>,虽然它需要整个链标记为async,并且需要单独的Connection,但可以有效地处理多个电话高效。与SqlClient不同,它节省了创建IEnumerable的努力,从DataReader or Dataset

将它作为UNIONWHERE SPB.SoftwareProductBuild IN ('build1', 'build2','build3')并让数据库对它进行排序。
更有效地利用连接,网络,脑力和CPU。