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 / 问题 / 243132
Accepted
Paul White
Paul White
Asked: 2019-07-18 12:47:55 +0800 CST2019-07-18 12:47:55 +0800 CST 2019-07-18 12:47:55 +0800 CST

哈希聚合救助

  • 772

聊天讨论中出现的一个问题:

我知道哈希连接救助会在内部切换到一种嵌套循环的东西。

SQL Server 对散列聚合救助做了什么(如果它可能发生的话)?

sql-server execution-plan
  • 1 1 个回答
  • 414 Views

1 个回答

  • Voted
  1. Best Answer
    Paul White
    2019-07-18T12:47:55+08:002019-07-18T12:47:55+08:00

    散列连接和散列聚合都在内部使用相同的运算符代码,尽管散列聚合仅使用单个(构建)输入。Craig Freedman 描述了哈希聚合的基本操作:

    与散列连接一样,散列聚合需要内存。在使用散列聚合执行查询之前,SQL Server 使用基数估计来估计我们需要多少内存来执行查询。使用散列连接,我们存储每个构建行,因此总内存需求与构建行的数量和大小成正比。连接的行数和连接的输出基数对连接的内存要求没有影响。使用散列聚合,我们为每个组存储一行,因此总内存需求实际上与输出组或行的数量和大小成正比。如果我们按列分组的唯一值和组更少,我们需要更少的内存。如果我们有更多的按列分组的唯一值和更多的组,我们需要更多的内存。

    他继续谈论哈希递归:

    那么,如果我们的内存不足会发生什么?同样,像哈希连接一样,如果内存不足,我们必须开始将行溢出到 tempdb。我们溢出一个或多个存储桶或分区,包括任何部分聚合的结果以及散列到溢出的存储桶或分区的任何其他新行。虽然我们不尝试聚合溢出的新行,但我们会对它们进行哈希处理并将它们分成几个桶或分区。一旦我们完成了所有输入组的处理,我们就会输出完成的内存组,并通过一次回读和聚合一个溢出的分区来重复算法。通过将溢出的行分成多个分区,我们减小了每个分区的大小,从而降低了算法需要重复多次的风险。

    救助

    Hash bailout的文档很少,但 Nacho Alonso Portillo 在What's the maximum level of recursion for the hash iterator before force bail-out 中提到过?

    该值是产品中硬编码的常数,其值为五 (5)。这意味着,在散列扫描运算符对任何不适合工作区授予的内存的给定子分区使用基于排序的算法之前,之前必须发生五次将原始分区细分为较小分区的尝试。

    提到的“哈希扫描运算符”引用CQScanHash了sqlmin.dll. 这个类负责实现我们在执行计划中看到的散列运算符(以所有形式,包括部分聚合和流不同)。

    救助算法

    这将我们带入您问题的核心 - 救助算法究竟是做什么的?它是“基于排序”还是基于“一种嵌套循环”?

    可以说两者兼而有之,这取决于您的观点。当哈希递归达到第 5 级时,内存中的哈希分区从哈希表变为哈希值上最初为空的 b 树索引。在 b-tree 索引中查找来自单个先前溢出的散列分区的每一行,并酌情插入(新组)或更新(维护聚合)。

    这一系列对 b 树的无序插入同样可以视为插入排序或索引嵌套循环查找。

    在任何情况下,这个回退算法都保证最终完成而不分配更多内存。如果可用于 b-tree 的空间不足以容纳来自溢出分区的所有分组键和聚合,则可能需要多次传递。

    一旦可用于保存 b-tree 索引的内存用完,任何进一步的行(来自当前溢出的分区)都将发送到单个新的tempdb分区(保证更小),并根据需要重复该过程。由于散列递归已经结束,溢出级别保持在 5。使用未记录的跟踪标志 7357 可以观察到一些处理细节。

    • 11

相关问题

  • 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