【问题标题】:SQL Server 2008 -- execute queries in parallelSQL Server 2008——并行执行查询
【发布时间】:2011-11-10 01:41:09
【问题描述】:

是否有一种简单的方法可以并行执行查询?我有一个类似这样的查询:

delete from TableA where id = @id
delete from TableB where id = @id
delete from TableC where id = @id
...

我想并行执行它们。我也可以使用 C#,但不确定如何使用。

【问题讨论】:

  • 请注意,如果这些表之间存在外键关系,则其性能可能不如您想象的那么好。
  • 是的,所有这些表都是独立的,除了一个主表,我会最后做。
  • 这真的是一个性能问题,值得通过并行处理使代码复杂化以从三个表中按 id 删除一些行吗?

标签: c# sql sql-server sql-server-2008


【解决方案1】:

第一个想法是拥有单独的线程和单独的连接,但我认为您可以使用异步回调在单个线程中通过多个连接来管理它:

string[] tables = new string[] { "TableA", "TableB", "TableC" ... };
var runningCommands = new List<SqlCommand>();
foreach(var table in tables)
{
  var conn = new SqlConnection(...);
  conn.Open();
  var cmd = new SqlCommand("DELETE FROM " + table + " WHERE id = @id");
  cmd.Parameters.Add(new SqlParameter("@id", id);
  cmd.BeginExecuteNonQuery(); 
  runningCommands.Add(cmd);
}
// now wait for all of them to finish executing
foreach(var cmd in runningCommands)
{
  cmd.EndExecuteNonQuery();
  cmd.Connection.Close();
}

【讨论】:

  • 并行化并不重要——请求仍然在数据库中按顺序执行。这就是您使用事务日志恢复到特定时间点的原因。
  • 三年不支持 .NET 1.1 的升级可能对您有所帮助:support.microsoft.com/lifecycle/search/…
  • @OMGPonies 仅对 DB 写入操作进行序列化。 DELETE 查询不止于此(解析查询,在数据库中找到正确的记录)。你至少可以从中受益。
  • 写查询也没有序列化。两个并发查询都可以写入内存中的不同页面。在他们成功提交之前,他们需要等到他们的最后一个 LSN 被写入日志文件。恢复到特定时间点只是意味着恢复到在那个时间点提交的那些事务。
  • @ssg - 日志文件始终按顺序写入,但这与特定用户事务无关。即他们只是独立地进行他们的工作并写入the log cache,在该事务提交之前,必须至少刷新到该事务的最后一个 LSN。
【解决方案2】:
    List<string> list;
    list.Add("query1");
    list.Add("query2");
    list.AsParallel().ForAll(query => ExecuteQuery(query));

【讨论】:

    【解决方案3】:

    使用 SSIS。将 3 执行 sql 任务放在控制流上。为每个任务添加删除语句。当包执行时,它们都会同时被执行。

    您还可以为每个语句创建一个作业,并安排它们同时运行。

    异步回调也可以工作,但上述 2 项对于具有 dba 技能的人来说更容易实现和管理。

    【讨论】:

      猜你喜欢
      • 2015-11-05
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      • 2013-07-03
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      相关资源
      最近更新 更多