数仓的等待视图中,为什么会有Hashjoin-nestloop
本文分享自华为云社区《GaussDB(DWS)等待视图之Hashjoin-nestloop》,作者:Arrow0lf。
1. 业务场景
众所周知,GaussDB(DWS)中有3种常见的join方式:HashJon/MergeJoin/NestLoop
但在有一些场景中,等待视图中等待状态会显示为:HashJoin-nestloop,如下图所示。这种表示什么含义?
2. 基本原理
为了明白该状态的原因,首先思考如下场景:当业务侧两张大表join时,如果由于未做analyze或统计信息不准,导致build hash的一侧选择了大表,且该表在join列上重复值很多,会导致hashjoin时内存膨胀,当内存不足时,hashjon算子会下盘,但是由于join列上存在大量重复值,下盘文件无法有效分裂,此时,如果将整个文件都读取到内存中,会导致内存占用很高,出现内存过载,导致其他业务内存不足报错。
为了解决该场景,在向量化hashjoin时,当使用内表创建的hash表过大导致内存不足时,不再强制进行hashjoin,会通过内外表交换或执行nestloop使查询平稳进行,防止出现内存报错,此时,等待视图状态为“HashJoin-nestloop”
上述特性通过hashjoin_spill_strategy参数控制,默认为0,取值范围为0-6的整数,详情可以参考产品文档(8.1.2及以上版本),简单来讲:
取值为0或5,hashjoin时会先尝试内外表交换,如果仍然内存占用高,会选择nestloop;
取值为1或6,hashjoin时会先尝试内外标交换,如果仍然内存占用高,会强行执行hashjoin;
取值为2,hashjoin行为和原本的行为保持一致,即使内存不够,也会强制执行hashjoin
3. 业务影响
当等待视图出现Hashjoin-nestloop时,可能会导致原来内存占用高,单能执行成功的语句,在被转换成nestloop后,可能会短时间执行不出来。尤其是当数据量变化较大,统计信息差异较大时,容易出现执行计划非最优场景下的性能劣化。
4. 解决方法
如果出现上述HashJoin-nestloop时间长,导致业务超时的情况。可以将参数hashjoin_spill_strategy设置为2进行规避。不再进行内外表交换或执行nestloop,使业务行为与之前的行为保持一致。
在内存充裕的场景下,可以全局设置为2。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Kepler 参数化查询优化方法
写在前面 本文主要介绍了发布于 2023 年 SIGMOD 的论文《Kepler: Robust Learning for Faster Parametric Query Optimization》,该文章针对参数化查询,将参数化查询优化与查询优化结合,旨在减少查询规划时间的同时提高查询性能。 为此,作者提出了一种端到端的、基于深度学习的参数化查询优化方法,名为 Kepler (K-plan Evolution for Parametric Query Optimization: Learned, Empirical, Robust)。 数化查询是指具有相同 SQL 结构,只在绑定的参数值上不同的一类查询。举个例子,考虑以下查询结构: 该查询结构可以看作一个参数化查询的模板,”?”处代表着不同的参数值。用户执行的 SQL 语句都具有该查询结构,只是实际的参数值可能不同,这就是一个参数化查询。这样的参数化查询在现代数据库中的使用十分频繁。由于其不断重复执行同一查询模板,为提升它的查询性能带来了机遇。 参数化查询优化 (PQO) 用于优化上述参数化查询的性能,目标是尽可能地减少查询规划时间...
- 下一篇
MySQL8.3 可以给 GTID 打标签了!
本文介绍了 MySQL 8.3 的一个新特性,给 GTID 打标签~ 作者:李富强,爱可生 DBA 团队成员,熟悉 MySQL,TiDB,OceanBase 等数据库。相信持续把对的事情做好一点,会有不一样的收获。 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 本文约 900 字,预计阅读需要 3 分钟。 摘要 MySQL 8.3 创新版于 2024 年 1 月 16 号发布,该版本扩展了 MySQL 复制和组复制中使用全局事务标识(GTID)的格式,支持给 GTID 打标签,以支持识别事务组。此增强功能可以为特定事务组的 GTID 分配唯一标识。例如:包含数据操作的事务可以很容易地与管理操作产生的事务区分开来,只需要比较他们的 GTID。 GTID 格式 原始格式 原始 GTID 格式是 source_id:transaction_id source_id 标识源服务器,通常用 server_uuid 表示。 transaction_id 代表事务在源上提交的顺序,例如要提交第一个事务的 transaction_id 为 1,要在同一源服务器上提交的第...
相关文章
文章评论
共有0条评论来说两句吧...