【问题标题】:SQL reduce data in join or whereSQL 减少 join 或 where 中的数据
【发布时间】:2020-03-25 10:05:58
【问题描述】:

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

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 中减少数据集是有意义的,但我找不到任何可以支持我的看法的东西。

【问题讨论】:

  • @juergend 您的第一句话是正确的,但第二句话在 Teradata(和大多数 DBMS)中不正确

标签: sql performance join teradata


【解决方案1】:

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

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

SQL 引擎分三个步骤处理查询:

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

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

【讨论】:

    【解决方案2】:

    大多数 SQL 方言将您的查询编译为执行计划。 Teradata 和大多数 SQL 系统使用“解释”命令显示预期的执行计划。 Teradata 也有一个直观的解释,很容易学习

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

    大多数 SQL 编译器都会使用当前表的统计信息(数据大小和分布)正确地解决这个问题

    在某些 SQL 系统中,您的第二个命令会更糟,因为它可能会强制由 tableB 上的所有字段构建完整的临时表

    应该是(我根本不推荐这种查询风格)

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

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

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

    【讨论】:

    • "在某些 SQL 系统中,您的第二个命令会更糟" - 真的有 DBMS 产品不会以相同的方式优化两者吗?你想到了哪一个?
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      DBMS 决定将用于解析查询的访问路径,您无法决定,但您可以执行某些操作,例如声明索引,以便 DBMS 在决定将使用哪个访问路径时考虑这些索引用于解决查询,然后您将获得更好的性能。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-04
        • 2011-05-07
        • 1970-01-01
        • 2021-08-21
        • 2015-09-19
        相关资源
        最近更新 更多