Sql 何处和连接操作顺序

Sql 何处和连接操作顺序,sql,teradata,Sql,Teradata,我的问题与此类似,但有点扭曲,所以我认为这样问是公平的 我正在使用Teradata。我有两张桌子:桌子一,桌子二 表1只有一个id列。 表2有以下列:id、val 我可能错了,但我认为这两种说法给出了相同的结果 报表1 SELECT table1.id, table2.val FROM table1 INNER JOIN table2 ON table1.id = table2.id WHERE table2.val<100 报表2 SELECT table1.id, table3.v

我的问题与此类似,但有点扭曲,所以我认为这样问是公平的

我正在使用Teradata。我有两张桌子:桌子一,桌子二

表1只有一个id列。 表2有以下列:id、val

我可能错了,但我认为这两种说法给出了相同的结果

报表1

SELECT table1.id, table2.val
FROM table1
INNER  JOIN table2
ON table1.id = table2.id
WHERE table2.val<100
报表2

SELECT table1.id, table3.val
FROM table1
INNER JOIN (
    SELECT *
    FROM table2
    WHERE val<100
)  table3
ON table1.id=table3.id
我的问题是,查询优化器是否足够聪明,可以 -首先执行WHERE子句,然后在语句1中执行JOIN -知道表3在语句2中实际上并不需要


我对SQL非常陌生,所以如果我误解了什么,请告诉我。

除非我遗漏了什么,否则你为什么需要表1

只需查询表2

Select id, val  
From table2  
WHERE val<100 
还是将表1中的行用作过滤器?i、 例如,表1是否仅包含表2中ID的子集

如果是这样,那么这也会起作用

 Select id, val  
 From table2  
 Where val<100 
   And id In (Select id 
              From table1)

但是要回答您的问题,是的,查询优化器应该足够智能,能够找出执行将逻辑指令转换为物理结果所需步骤的最佳顺序。它使用数据库在每个表上维护的排序统计信息来确定要执行的操作以及要使用的连接逻辑的类型,例如,执行操作的顺序,以最小化磁盘IO和处理成本。

这将取决于表大小、索引、键分布等许多因素,您只需检查执行计划:

您不会说是哪个数据库,但以下是一些方法:


第一季度。首先执行WHERE子句,然后在语句1中执行JOIN

问题是,如果您切换内部联接的顺序,即表2内部联接表1,那么我猜可以在准备阶段的联接操作之前处理WHERE子句。但是,我想即使您不更改原始查询,如果优化器认为获取整行的连接操作过于昂贵,那么优化器也应该能够切换它们的顺序,因此它将首先应用于何处。只是我的猜测

问题2。知道表3在语句2中实际上并不需要


Teradata将以需要派生表的方式解释第二个查询,因此,它将继续处理表3所涉及的操作。

根据相关表的统计信息和索引的可用性,优化器中的查询重写机制可能会或可能不会选择在扫描表1之前扫描表2中val<100的记录

在某些情况下,根据数据统计、联接、索引和统计信息,您可能会发现优化器在您认为应该删除查询计划中的记录时,并没有删除这些记录。即使您有一个派生表,如示例中的表。只需在派生表中放置GROUP by,即可强制优化器处理派生表。然后,优化器必须在它可以考虑在示例中解析两个表之间的连接之前,用聚合来解决该组。
SELECT table1.id, table3.val
FROM table1
INNER JOIN (
    SELECT table2.id, tabl2.val
    FROM table2
    WHERE val<100
    GROUP BY 1,2
)  table3
ON table1.id=table3.id
这并不是说你的标准方法应该是在你的代码中使用它。当我有一个查询计划时,这通常是我最后的手段之一,因为该计划没有在足够早的时间内消除计划中的无关记录,导致过多的数据被扫描并通过各种SPOOL文件传输。这只是一种技术,当您遇到这种情况时,可以将其放在工具箱中


查询重写机制从一个版本不断更新到下一个版本,有关其工作原理的详细信息可以在for Teradata 13.0中找到。

我原以为查询优化人员会为这两个版本提出相同的计划。尝试运行EXPLAIN plan进行验证。他正在进行内部联接,因此他将结果集限制在两个表中的值所在的位置。我很确定Russell确实说出了哪个DB。这是一个@Conrad Frix,谢谢阅读,我已经添加了链接