数仓的等待视图中,为什么会有Hashjoin-nestloop?

💡 原文中文,约1200字,阅读约需3分钟。
📝

内容提要

本文介绍了GaussDB(DWS)中的HashJoin-nestloop等待视图的含义和影响。当内存不足时,会通过内外表交换或执行nestloop使查询平稳进行,防止内存报错。建议将参数hashjoin_spill_strategy设置为2以规避问题。

🔎

延伸解读

HashJoin-nestloop 的触发条件

当两张大表进行 join 时,如果未做 analyze 或统计信息不准确,可能导致 build hash 的一侧选择了大表,且该表在 join 列上重复值很多。此时 hashjoin 内存膨胀,内存不足时算子下盘,但由于重复值多,下盘文件无法有效分裂,若整个文件读入内存会导致内存过载。为避免内存报错,系统会通过内外表交换或执行 nestloop 使查询平稳进行,等待视图便显示为 HashJoin-nestloop。

参数 hashjoin_spill_strategy 的行为差异

该参数默认为 0,取值范围 0-6。取值为 0 或 5 时,hashjoin 先尝试内外表交换,若内存仍高则选择 nestloop;取值为 1 或 6 时,先尝试内外表交换,若内存仍高则强行执行 hashjoin;取值为 2 时,hashjoin 行为与原本一致,即使内存不够也强制执行 hashjoin。不同取值直接影响内存不足时的处理策略。

性能劣化风险与规避方法

出现 HashJoin-nestloop 时,原本内存占用高但能执行成功的语句,被转换成 nestloop 后可能短时间执行不出来。尤其当数据量变化较大、统计信息差异较大时,容易出现执行计划非最优场景下的性能劣化。若因此导致业务超时,可将 hashjoin_spill_strategy 设置为 2 进行规避,不再进行内外表交换或执行 nestloop,使业务行为与之前保持一致。在内存充裕的场景下,可以全局设置为 2。

❓

Q&A

GaussDB(DWS)等待视图中出现HashJoin-nestloop是什么意思?

HashJoin-nestloop表示在向量化hashjoin时,当使用内表创建的hash表过大导致内存不足时,系统不再强制进行hashjoin,而是通过内外表交换或执行nestloop使查询平稳进行,以防止内存报错。

为什么会出现HashJoin-nestloop等待状态?

当两张大表join时,如果未做analyze或统计信息不准,导致build hash的一侧选择了大表,且该表在join列上重复值很多,会导致hashjoin时内存膨胀。当内存不足时,hashjoin算子会下盘,但由于join列上存在大量重复值,下盘文件无法有效分裂,此时如果将整个文件都读取到内存中,会导致内存占用很高,出现内存过载。为了解决该场景,系统会通过内外表交换或执行nestloop使查询平稳进行,此时等待视图状态为HashJoin-nestloop。

hashjoin_spill_strategy参数的作用是什么?取值范围是多少?

hashjoin_spill_strategy参数用于控制hashjoin的行为,默认为0,取值范围为0-6的整数。取值为0或5时,hashjoin时会先尝试内外表交换,如果仍然内存占用高,会选择nestloop;取值为1或6时,hashjoin时会先尝试内外表交换,如果仍然内存占用高,会强行执行hashjoin;取值为2时,hashjoin行为和原本的行为保持一致,即使内存不够,也会强制执行hashjoin。

HashJoin-nestloop对业务有什么影响?

当等待视图出现HashJoin-nestloop时,可能会导致原来内存占用高但能执行成功的语句,在被转换成nestloop后,可能会短时间执行不出来。尤其是当数据量变化较大,统计信息差异较大时,容易出现执行计划非最优场景下的性能劣化。

如何解决HashJoin-nestloop导致的业务超时问题?

如果出现HashJoin-nestloop时间长,导致业务超时的情况,可以将参数hashjoin_spill_strategy设置为2进行规避。这样不再进行内外表交换或执行nestloop,使业务行为与之前的行为保持一致。在内存充裕的场景下,可以全局设置为2。

GaussDB(DWS)中有哪些常见的join方式?

GaussDB(DWS)中有3种常见的join方式:HashJoin、MergeJoin和NestLoop。

🏷️

标签

➡️

继续阅读