如何同时运行两个耗时的SQL SELECT语句

3
在SQL中,是否有一种同时运行多个SELECT语句并将结果连接起来的方法?我在互联网上看到的大多数示例似乎涉及按顺序运行SELECT语句,然后是JOIN和其他语句。
代码示例如下:
SELECT x, y FROM Table apples WHERE ... as t1
left join
    (SELECT x, y FROM Table oranges WHERE ... as t2)
on
     t1.x = t2.x

现在想象一下,如果SELECT x, y FROM Table apples WHERE ... as t1花费了很长时间,我该如何同时运行上述两个SELECT语句(类似于Java或C#中的线程调用)以节省时间?或者Oracle已经这样做了吗?
谢谢

另外再建一张表来存储 ks 和相应计数,并使用触发器来维护该表如何? - zerkms
有趣。那个的SQL语句会是什么样子?抱歉,我的SQL经验有限。 - Fuzzy Analysis
顺便说一句,SUM(WHEN Age > Palt THEN 1 ELSE 0 END) - zerkms
抱歉各位,我认为原始示例的语法偏离了我的主要问题,即同时执行SELECT语句,因此我已更改了示例。非常抱歉。我已经给那些回答早期示例的人点赞了。 - Fuzzy Analysis
1
“which was simultaneous SELECT statement execution” --- 一般的解决方案是重写查询,以避免需要同时执行。 - zerkms
是的,甚至可以更好地设计数据库。干杯 - Fuzzy Analysis
3个回答

3
可以通过单个查询完成所有操作,无需使用连接或子查询:
  SELECT ks,
         COUNT(*) AS '# Tasks',
         SUM(CASE WHEN Age > Palt THEN 1 ELSE 0 END) AS '# Late'
    FROM Table
GROUP BY ks

作为可能的性能提升,值得尝试创建一个复合的(ks, Age, Palt)指数。


1
在这种情况下,查询优化可能会成功,但我觉得它并没有回答核心问题。 - David Aldridge
1
@David Aldridge:这得看情况。通常人们试图通过错误的方式来解决问题(由于缺乏经验、知识或其他原因)。因此,最终解决方案不会是对所提问的直接答案,而是一些更有效/最佳实践方法来解决原始任务。 - zerkms
2
我非常支持寻找更简单的解决方案,特别是当性能成为问题的根源时——我的首选总是优化查询,而你展示的方法在这种情况下是我会尝试的(不过我认为你需要在其中加入一个CASE关键字?)。然而,这个问题本身提出了有趣的架构问题,特别是对于非数据库专家来说。 - David Aldridge
1
@David Aldridge:确实,这就是为什么我给你点赞的原因 :-) - zerkms

3
不,Oracle没有同时执行它们。最接近的方法是并行查询,在其中单个查询的阶段可以自动分配到多个并行查询会话中,并由查询协调器会话组合结果。
您可以尝试将多个查询的逻辑组合成一个(正如zerkms建议的那样),并优化查询以使用覆盖索引(例如)--换句话说,是慢执行查询的标准方法。
将分别执行的查询结果组合在一起可能存在致命问题之一是它们不一致。每个查询通常对应寻找一致数据的略有不同的时间点,除非您使用闪回查询来获得稍旧的结果。
如果数据是静态的,则可以使用DBMS_Scheduler同时运行多个查询,加载到共同的表中,然后从那里选择。DBMS_Scheduler可以定义进程链,这些链可以串行或并行地执行,并提供非常复杂的结束条件检查以确定应何时执行哪些步骤。但它是一个大型工具,通常用于批处理(例如数据仓库ELT过程)。

1
它们不一致的问题是什么?关于事务呢? - zerkms
1
在Oracle术语中,您可以使用串行化读一致性模式下的事务来获取两个查询以查看相同的一致性点,但是您正在寻找使用两个不同进程执行的两个查询--它们不能共享同一个事务。 - David Aldridge
1
从这个角度考虑,这很有道理,我之前没有想到过。 - zerkms
1
如果数据已知为静态的,那当然这就是一个无意义的问题。 - David Aldridge
我认为zerkms和你都给出了很好的答案,所以非常感谢。在这里很难选择“最佳”答案。 - Fuzzy Analysis

1
Oracle 12c允许并发执行union all。这仍然不能并行运行执行计划的每个步骤,但它可以更接近。
然而,几乎从不需要该功能。常规并行查询能够为单个查询使用所有可用的系统资源。
如果APPLES和ORANGES足够大,每个表都有足够的工作量分配。某些操作,如排序和散列,将并发执行。这就是为什么Oracle有时会分配两倍于请求的并行度的并行服务器。
如果APPLES和ORANGES很小,数据库必须担心同时运行多个查询。为了不值得的事情启动和协调多个线程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接