【问题标题】:Transact SQL parallel query executionTransact SQL 并行查询执行
【发布时间】:2011-11-23 12:50:20
【问题描述】:

假设我有

INSERT INTO @tmp1 (ID) SELECT ID FROM Table1 WHERE Name = 'A'
INSERT INTO @tmp2 (ID) SELECT ID FROM Table2 WHERE Name = 'B'
SELECT ID FROM @tmp1 UNION ALL SELECT ID FROM @tmp3

我想并行运行查询 1 和 2,然后在完成后合并结果。

有没有办法在纯 T-SQL 中执行此操作,或者检查它是否会自动执行此操作?

需要它的人的背景:我调查了一个复杂的搜索,其中有多个条件后来组合在一起(term OR (term2 AND term3) OR term4 AND item5=term5),因此我调查它是否有用并行执行那些基本上不相关的条件,然后组合结果表(并计算排名、权重等)。

例如应该是几个结果集:

SELECT COUNT(*) @tmp1 union @tmp3
SELECT ID from (@tmp1 union @tmp2) WHERE ...
SELECT * from TABLE3 where ID IN (SELECT ID FROM @tmp1 union @tmp2)
SELECT * from TABLE4 where ID IN (SELECT ID FROM @tmp1 union @tmp2)

【问题讨论】:

  • @Ioannis Karadimas:不相关。并行性是一种具有多个线程的查询。不同的会话具有并行查询
  • 你是对的。我已删除评论。
  • -1 用于愚蠢的问题。见下面的 cmets

标签: sql-server tsql


【解决方案1】:

你没有。 SQL 不是这样工作的:它不是程序性的。由于其他连接,它会导致竞争条件和数据问题

表变量的范围也仅限于批处理和连接,因此您无法通过 2 个连接共享结果,以防万一。

无论如何,你只需要这个,除非你给了我们一个不好的例子:

SELECT ID FROM Table1 WHERE Name = 'A'
UNION
SELECT ID FROM Table2 WHERE Name = 'B'

由于这种程序性思维,我怀疑您正在考虑“并行运行”。您实际想要的问题和目标是什么?

注意:表变量不允许并行操作:Can queries that read table variables generate parallel exection plans in SQL Server 2008?

【讨论】:

  • OP 正在查询两个不同的表——不是同一个表:这行不通。
  • 是Table1和Table2,例子只是说明两个select是没有关系的。我的实际问题是我调查了复杂搜索的所有可能解决方案。
  • @queen3:那么,给我们实际问题和代码。不要简化问题,然后抱怨/否决简化问题的答案
  • 我不抱怨也不反对任何事情,实际上我根本不在乎。我所需要的只是知道并行化查询的可能性,或者查看 SQL 是否可以使用提示或签入 ex。计划。我已经有 10 种不同的方法可以尝试,但我知道一切可以做出决定。我唯一不知道的是是否有可能......见上文。
【解决方案2】:

您无法决定要并行化什么 - SQL Server 的优化器可以。优化器将使用的最大工作单元是单个语句 - 因此,您可以找到一种方法将查询表达为单个语句,然后依靠 SQL Server 来完成它的工作,它通常会做得很好。

如果在构建查询后,性能不可接受,那么您可以考虑应用提示或强制使用某些计划。很多人将他们的查询分解为多个语句,或者相信他们可以比 SQL Server 做得更好,或者因为这是他们“自然地”思考手头任务的方式。两者都是“错误的”(对于某些错误值),但如果存在自然故障,您可以使用公用表表达式复制它 - 这将允许您命名问题的每个子部分,然后将它们组合起来一起,作为单个语句的一部分。

例如:

;WITH TabA AS (
     SELECT ID FROM Table1 WHERE Name = 'A'
), TabB AS (
     SELECT ID FROM Table2 WHERE Name = 'B'
)
SELECT ID FROM TabA UNION ALL SELECT ID FROM TabB

这将允许服务器决定如何最好地解决这个查询(例如,决定是否将中间结果存储在“临时”表中)


在您的其他 cmet 中看到您讨论必须“处理”中间结果 - 这仍然可以通过 CTE 完成(如果这不仅仅是您无法表达“最终”结果的情况作为单个查询),例如:

;WITH TabA AS (
   SELECT ID FROM Table1 WHERE Name = 'A'
), TabAWithCalcs AS (
   SELECT ID,(ID*5+6) as ModID from TabA
)
SELECT * FROM TabAWithCalcs

【讨论】:

  • 好答案,您应该加入我们的 dba.se 聊天 chat.stackexchange.com/rooms/179/the-heap
  • 如果使用#temp 表而不是cte 表(必须是由于缺少具体化提示),那么我不相信SQL Server 会并行创建两个临时表。 SQL Server 仍然主要是超出单个语句范围的程序。
【解决方案3】:

为什么不只是:

SELECT ID FROM Table1 WHERE Name = 'A'
UNION ALL
SELECT ID FROM Table2 WHERE Name = 'B'

那么,如果 SQL Server 想要并行运行这两个选择,它会自行执行。

否则,如果这不切实际,我们需要更多背景信息来说明您想要实现的目标。

【讨论】:

  • 因为在合并它们之前我可能需要对单个结果进行处理——比如计算权重。总而言之,我只需要并行问题的答案。
  • 那么我们需要更多细节。但是你不能与 SQL 并行。如果您确实想要并行,那么这是客户端代码的一个功能,它将用(例如)C# 编写。它必须在两个不同的线程上打开到数据库的两个连接,然后在客户端业务逻辑中管理结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多