14

我的问题类似于这种SQL 操作顺序,但有一点扭曲,所以我认为问这个问题是公平的。

我正在使用 Teradata。我有 2 张桌子: table1, table2.

table1只有一id列。
table2具有以下列: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
- 知道语句 2 中实际上不需要表 3

我对 SQL 很陌生,所以如果我有任何误解,请教育我。

4

4 回答 4

6

这取决于很多事情(表大小、索引、键分布等),您应该只检查执行计划:

你不说哪个数据库,但这里有一些方法:
MySql EXPLAIN
SQL Server SET SHOWPLAN_ALL (Transact-SQL)
Oracle EXPLAIN PLAN

teradata 中的解释是什么?
Teradata 使用 Visual Explain 和 XML 计划记录更快地捕获和比较计划

于 2010-10-18T15:27:18.853 回答
4

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

在某些情况下,根据数据人口统计、连接、索引和统计信息,您可能会发现优化器并没有在您认为应该删除查询计划中的记录时。即使您有一个派生表,例如您的示例中的表。您可以通过在派生表中简单地放置一个 GROUP BY 来强制优化器处理派生表。然后,优化器有义务在考虑解决示例中两个表之间的连接之前解析 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 文件携带。当您遇到这种情况时,这只是您可以放入工具包中的一种技术。

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

于 2010-10-21T14:04:26.697 回答
1

除非我遗漏了什么,为什么你甚至需要 Table1?

只需查询 Table2

Select id, val  
From table2  
WHERE val<100 

还是您使用 table1 中的行作为过滤器?即,表 1 是否仅包含表 2 中 Id 的子集?

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

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

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

于 2010-10-18T15:20:19.383 回答
0

Q1。先执行 WHERE 子句,然后在语句 1 中执行 JOIN

问题是,如果你切换内连接的顺序,即table2 INNER JOIN table1,那么我猜WHERE子句可以在JOIN操作之前处理,在准备阶段。但是,我想即使您不更改原始查询,优化器也应该能够切换它们的顺序,如果它认为连接操作在获取整行时成本太高,那么它将首先应用 WHERE。只是我的猜测。

Q2。知道语句 2 中实际上不需要表 3

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

于 2010-10-19T05:27:26.437 回答