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 / 问题 / 254947
Accepted
Martin Smith
Martin Smith
Asked: 2019-12-06 13:08:10 +0800 CST2019-12-06 13:08:10 +0800 CST 2019-12-06 13:08:10 +0800 CST

当构建端为空时,SQL Server 为什么/何时评估内部哈希连接的探测端?

  • 772

设置

DROP TABLE IF EXISTS #EmptyTable, #BigTable

CREATE TABLE #EmptyTable(A int);
CREATE TABLE #BigTable(A int);

INSERT INTO #BigTable
SELECT TOP 10000000 CRYPT_GEN_RANDOM(3)
FROM   sys.all_objects o1,
       sys.all_objects o2,
       sys.all_objects o3;

询问

WITH agg
     AS (SELECT DISTINCT a
         FROM   #BigTable)
SELECT *
FROM   #EmptyTable E
       INNER HASH JOIN agg B
                    ON B.A = E.A;

执行计划

在此处输入图像描述

问题

这是我今天之前没有注意到的现象的简化重现。我对内部散列连接的期望是,如果构建输入为空,则不应执行探测端,因为连接不会返回任何行。上面的示例与此相矛盾,并从表中读取了 1000 万行。这使查询的执行时间增加了 2.196 秒 (99.9%)。

额外的观察

  1. 执行OPTION (MAXDOP 1)计划没有从中读取任何行。适用于散列连接内部的所有运算符#BigTable。ActualExecutions0
  2. 对于查询SELECT * FROM #EmptyTable E INNER HASH JOIN #BigTable B ON B.A = E.A——我得到一个并行计划,散列连接内部的扫描运算符确实有ActualExecutionsDOP,但仍然没有读取任何行。该计划没有重新分区流运算符(或聚合)

问题

这里发生了什么?为什么原始计划会出现问题而其他情况却不会?

sql-server execution-plan
  • 2 2 个回答
  • 764 Views

2 个回答

  • Voted
  1. Best Answer
    Paul White
    2019-12-06T14:47:20+08:002019-12-06T14:47:20+08:00

    当构建为空时不运行连接的探测端是一种优化。当探测端有子分支时,即当有交换运算符时,它不适用于并行行模式散列连接。

    许多年前,Adam Machanic 在现已关闭的 Connect 反馈网站上发表了类似的报告。该场景是探针端的启动过滤器,它意外地运行了它的子操作符。Microsoft 的回答是,引擎需要保证某些结构已初始化,唯一明智的强制执行方式是确保打开探测端运算符。

    我自己对细节的回忆是,不初始化子树会导致难以修复的并行时序错误。确保子分支启动是解决这些问题的一种方法。

    批处理模式哈希连接没有这种副作用,因为管理线程的方式不同。

    在您的特定情况下,效果更为明显,因为哈希聚合正在阻塞;它在迭代器的 Open() 调用期间消耗了它的全部输入。当探测端只有流式运算符时,性能影响通常会更有限,具体取决于将第一行返回到散列连接的探测端所需的工作量。

    • 10
  2. Gokhan
    2019-12-06T19:34:40+08:002019-12-06T19:34:40+08:00

    不是答案,但如果不强制执行散列连接,则该查询不会将散列连接作为计划。解决方法是如果表中存在行则将位变量设置为 1,如果不存在则设置为 0,而不是使用#Emptytable (Select * from #Emptytable where @bit =1)

    并在最后添加一个选项 recompile ,不会执行。

    我认为如果不使用强制并且如果需要强制存在解决方法,那么这种情况永远不会发生。

    • 1

相关问题

  • 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