AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 276712
Accepted
merger
merger
Asked: 2020-10-08 10:24:47 +0800 CST2020-10-08 10:24:47 +0800 CST 2020-10-08 10:24:47 +0800 CST

左哈希连接总是比左外连接更好吗?

  • 772

我有一个运行速度很慢的查询(见下文)。在寻找改进方法时,我们发现如果我们将LEFT OUTER JOIN替换为LEFT HASH JOIN,查询的运行速度会快十倍

结果似乎是一样的。是吗?在什么情况下它不会返回相同的结果?有什么区别?在运行 LEFT HASH JOIN 而不是 LEFT OUTER JOIN 时,我应该注意什么?

查询中的[ABC].[ExternalTable]表是我添加为外部表的不同服务器上的视图

SELECT t.foo, t.bar, t.data
FROM [dbo].[Table] as t
LEFT OUTER JOIN [ABC].[ExternalTable] as s ON s.foo = t.foo and s.bar = t.bar and s.data = t.data
WHERE s.foo is null and s.bar IS NULL and s.data IS NULL
sql-server hashing
  • 3 3 个回答
  • 4767 Views

3 个回答

  • Voted
  1. Best Answer
    Hannah Vernon
    2020-10-08T10:30:53+08:002020-10-08T10:30:53+08:00

    从语义上讲,这两个查询是相同的。LOOPvs只是告诉 SQL Server使用HASH哪个选项来返回结果。如果您在不使用LOOPor的情况下运行查询HASH,SQL Server 可能会选择其中任何一个选项,具体取决于它认为性能最佳的选项。这两个选项按设计返回相同的结果。稍微不同1,在这种情况下,关键字HASH和LOOP是所谓的连接提示,是 Transact-SQL 中的三种提示之一。更让您感到困惑的是,您还可以将连接提示指定为查询提示,尽管两种情况下的效果不一定相同。请注意,提供这些类型的连接提示意味着FORCE ORDER提示,它指定在查询优化期间保留查询语法指示的连接顺序(有关更多详细信息,请参见下面的 Paul 回答)。

    SQL Server 使用查询中每个表的统计信息JOIN来对 T-SQL 查询语句中的每个表进行何种物理操作做出明智的选择。

    在这种情况下,由于[ExternalTable]是通过链接服务器引用的视图,SQL Server 可能希望表中有 1 行 - 即它不知道需要多少行。

    您可以向查询添加连接提示以强制进行合并连接,也可以简单地将行从[ExternalTable]带有聚集索引的本地 #temp 表中复制,然后针对它运行查询。

    哈希连接的完整语法是:

    LEFT OUTER HASH JOIN [ABC].[ExternalTable] s ON s.foot = t.foo .....
    

    join 语句中的版本HASH允许 SQL Server 选择连接类型,在您的特定情况下,它很可能选择 LOOP 连接,您可以强制使用:

    LEFT OUTER LOOP JOIN [ABC].[ExternalTable] s ON s.foot = t.foo .....
    

    我通常不建议指定连接类型,因为大多数时候 SQL Server 非常有能力选择最合适的连接运算符样式。


    1 - 感谢 Andriy 的措辞。

    • 12
  2. Tibor Karaszi
    2020-10-09T03:56:39+08:002020-10-09T03:56:39+08:00

    我只想在这里添加一些其他答案和评论:

    您正在将苹果与橙子进行比较。

    OUTER 是一个逻辑连接运算符。它指定您要保留行的一侧。因此需要说左或右。可以省略 OUTER 这个词,意思是 LEFT JOIN 与 LEFT OUTER JOIN 相同。

    HASH 是 SQL Server 的指令,指定如何执行您要求的任何连接(例如左连接)。我们通常避免提示,让优化器决定如何做。反过来,优化器依赖于诸如统计数据之类的东西来尝试提出执行您所要求的最佳方法。覆盖优化器的一个缺点是优化器在事情发生变化时调整的自由度较小,例如其中一个表中有更多数据,或者您添加或删除了索引。

    所以,说 LEFT HASH JOIN 和说 LEFT OUTER HASH JOIN 是一样的。OUTER 这个词是可选的。

    • 8
  3. Paul White
    2020-10-16T04:49:53+08:002020-10-16T04:49:53+08:00

    LEFT HASH JOIN运行 a而不是 a时,我应该注意LEFT OUTER JOIN什么?

    是的。使用类似的连接提示LEFT HASH JOIN会强制查询中指定的表的连接顺序。它强制优化器以文本顺序连接表,就像您也添加了一样OPTION (FORCE ORDER)。

    使用连接提示与 具有所有相同的效果FORCE ORDER,包括禁用聚合的重新定位和引入部分聚合。

    对连接提示要格外小心。它们对查询优化器的限制比大多数人意识到的要多得多。

    • 5

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve