【问题标题】:How to run the subquery first in presto如何在 presto 中首先运行子查询
【发布时间】:2023-08-19 05:26:02
【问题描述】:

我有以下疑问:

select * 
from Table1 
where NUMid in (select NUMid 
                from Table2 
                where email = 'xyz@gmail.com')

我的意图是从 table2 中获取电子邮件值等于 xyz@gmail.com 的所有 NUMid 列表,并使用这些 NUMid 列表从 Table1 中查询。

在 presto 中,查询首先运行外部查询。有没有办法运行和存储内部查询的结果,然后在 presto 的外部查询中使用它?

【问题讨论】:

  • 在大多数 SQL 版本中,您将索引 Table2,以便上述子查询查找非常快。但是,Presto 不支持常规索引,所以我不知道这里可以做什么。
  • 奇怪,因为内部查询会大大简化外部查询!你担心因为它需要很长时间吗?我想知道如果通过JOIN 完成它是否会更有效地运行?

标签: sql amazon-web-services amazon-athena presto in-clause


【解决方案1】:

优化器可以为所欲为。在这种情况下,它应该运行一次内部查询,然后基本上执行JOIN(技术上是“半连接”)操作。

在许多数据库中,exists 带有适当的索引可以解决性能问题。

如果您想确保子查询只计算一次,您可以将其移至ON 子句。正确的等效查询如下所示:

select t1.* 
from Table1 t1 join
     (select distinct t2.NUMid 
      from Table2 t2
      where t2.email = 'xyz@gmail.com'
     ) t2
     on t1.NUMid = t2.NUMid;

select distinct 对于join 代码与in 代码等效很重要。但是,如果您知道没有重复项,则更通俗地说是没有子查询:

select t1.* 
from Table1 t1 join
     Table2 t2
     on t1.NUMid = t2.NUMid
where t2.email = 'xyz@gmail.com'

【讨论】:

    【解决方案2】:

    Presto 和Trino (formerly known as PrestoSQL) 将该查询作为“半联接”操作执行:它使用来自内部查询的行构建内存索引,并针对该索引探测外部查询的行.如果存在值,则发出来自外部查询的行,否则,将其过滤掉。

    在最新版本的 Trino 中,有一个称为“动态过滤”的功能,它允许查询引擎根据从内部查询动态获取的信息,在源头动态过滤和修剪外部查询的数据。您可以在以下博客文章中了解更多信息:

    【讨论】:

      最近更新 更多