SQL 减少 join 或 where 中的数据

SQL reduce data in join or where

我想知道什么更快,假设我有以下查询并且它们检索相同的数据

select * from tableA a inner join tableB b on a.id = b.id where b.columnX = value

select * from tableA inner join (select * from tableB where b.columnX = value) b on a.id = b.id

我认为提前从 tableB 减少数据集是有意义的,但我没有找到任何东西来支持我的看法。

在Teradata这样的数据库中,两者应该具有完全相同的性能特征。

SQL 不是过程语言。 SQL 查询 描述 结果集。它没有指定操作顺序。

SQL 引擎分三步处理查询:

  1. 解析查询。
  2. 优化解析后的查询。
  3. 执行优化查询。

第二步为引擎提供了很大的灵活性。大多数查询引擎会非常智能地忽略子查询、使用基于 where 子句的索引和分区等等。

大多数 SQL 方言将您的查询编译成执行计划。 Teradata 和大多数 SQL 系统使用 "explain" 命令显示预期的执行计划。 Teradata 也有一个可视化的解释,很容易学习

这取决于每个table中的数据量和密钥类型,如果有任何方法是有利的

大多数 SQL 编译器将使用当前 table 统计数据(数据大小和传播)正确解决这个问题

在某些 SQL 系统中,您的第二个命令会更糟,因为它可能会强制 table 由 tableB

上的所有字段构建一个完整的临时 table

应该是(完全不是我推荐这种查询方式)

select * from tableA inner join (select id from tableB where columnX = value) b on a.id = b.id

在大多数情况下,不必担心这一点,除非您有特定的性能问题,然后使用解释命令找出原因

一般而言,更好的方法是使用常见的 table 表达式 (CTE) 来分解问题。这会带来更好的查询,可以长期测试和维护

每当您遇到这样的场景,您觉得在 teradata 中哪个查询会更快地产生结果,请在 teradata 中使用 EXPLAIN 计划 - 这将正确地指示 PE 将如何检索记录。如果您使用的是 Teradata sql 助手,那么您可以 select 查询并按 F6。

DBMS 决定将用于解析查询的访问路径,您不能决定它,但您可以做某些事情,例如声明索引,以便 DBMS 在决定哪个访问路径时考虑这些索引它将用于解析查询,然后您将获得更好的性能。

例如,在这个例子中,您通过 b.columnX 过滤 tableB,通常如果没有为 tableB 声明的索引,DBMS 将必须执行完整的 table 扫描以确定哪些行满足该条件,但假设您通过 columnX 在 tableB 上声明了一个索引,在这种情况下,DBMS 可能会考虑该索引并确定使用该索引的访问路径,获得比完整 table 扫描更好的性能,特别是如果 table 很大。