{"componentChunkName":"component---src-templates-acg-portal-new-template-tsx","path":"/Vmt8jdlx5","result":{"data":{"markdownRemark":{"html":"<h2 id=\"1-概述\"><a href=\"#1-%E6%A6%82%E8%BF%B0\" aria-label=\"1 概述 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. 概述</h2>\n<p>向量化执行引擎是 BMR Spark 内置的查询加速能力，基于 <strong>Apache Gluten</strong> 与 <strong>Velox</strong> 构建，把 Spark SQL 的算子计算下沉到 C++ 原生向量化引擎执行。</p>\n<p>它完全兼容 Apache Spark API，业务代码与 SQL 无需任何改造；BMR 集群已默认开启，您不需要做额外配置。 对于当前尚未支持的算子、数据类型、文件格式或函数，引擎会自动回退到原生 Spark 执行，结果保持正确。</p>\n<h3 id=\"11-支持的版本\"><a href=\"#11-%E6%94%AF%E6%8C%81%E7%9A%84%E7%89%88%E6%9C%AC\" aria-label=\"11 支持的版本 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1.1 支持的版本</h3>\n<table>\n<thead>\n<tr>\n<th>BMR 版本</th>\n<th>Spark 版本</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>BMR 3.5.2</td>\n<td>Spark 3.3.2</td>\n<td>已支持</td>\n</tr>\n<tr>\n<td>BMR 3.7.3 及以上</td>\n<td>Spark 3.5.5</td>\n<td>已支持</td>\n</tr>\n<tr>\n<td>其他 BMR 版本</td>\n<td>—</td>\n<td>暂不提供向量化执行能力</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"12-性能表现\"><a href=\"#12-%E6%80%A7%E8%83%BD%E8%A1%A8%E7%8E%B0\" aria-label=\"12 性能表现 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1.2 性能表现</h3>\n<p>在 256 CU 计算规模、5 TB TPC-DS 数据集下，Spark 3.5.5 开启向量化执行后，整体性能相比基线 <strong>提升 3.98 倍</strong>。</p>\n<table>\n<thead>\n<tr>\n<th>测试项</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>计算规模</td>\n<td>256 CU</td>\n</tr>\n<tr>\n<td>数据集</td>\n<td>TPC-DS 5 TB</td>\n</tr>\n<tr>\n<td>Spark 版本</td>\n<td>3.5.5</td>\n</tr>\n<tr>\n<td>对比基线</td>\n<td>原生 Spark</td>\n</tr>\n<tr>\n<td>整体结果</td>\n<td>性能提升 3.98 倍</td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"2-原理介绍\"><a href=\"#2-%E5%8E%9F%E7%90%86%E4%BB%8B%E7%BB%8D\" aria-label=\"2 原理介绍 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. 原理介绍</h2>\n<p>随着 SSD 与高速网卡的普及，大数据计算的瓶颈已经从 IO 转向 CPU。而 Spark 运行在 JVM 之上， 即使有 Codegen 这类优化，也仍受字节码长度、方法参数个数等限制，难以充分利用现代 CPU 的向量化指令。</p>\n<p>向量化执行引擎的做法是<strong>只替换计算部分，不改变 Spark 的架构</strong>：SQL 解析、Catalyst 优化、 任务调度、失败重试、整个分布式框架都仍由 Spark 负责；Gluten 在物理计划阶段把可下沉的算子改写为原生算子， 序列化成 Substrait 计划后经 JNI 交给 Velox，由 C++ 引擎完成单个 Task 的实际计算。</p>\n<p>性能提升主要来自四个方面：</p>\n<table>\n<thead>\n<tr>\n<th>加速来源</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>列式批处理与 SIMD</td>\n<td>数据以列式批（每批默认 4096 行）在内存中连续存放，单条 CPU 指令可处理多个数据， 同时消除了逐行处理带来的虚函数调用与解释执行开销</td>\n</tr>\n<tr>\n<td>原生堆外内存</td>\n<td>计算全程在堆外进行，避免 JVM 对象开销与 GC 停顿</td>\n</tr>\n<tr>\n<td>原生列式 Shuffle</td>\n<td>直接以列式格式落盘与网络传输，省去行列转换和 Java 序列化</td>\n</tr>\n<tr>\n<td>延迟物化与过滤下推</td>\n<td>过滤条件下推到文件读取层，未命中的列不做解码，减少无效 IO 与计算</td>\n</tr>\n</tbody>\n</table>\n<p><img src=\"https://bce.bdstatic.com/doc/bce-doc/BMR/k1_1973b38.png\" alt=\"k1.png\"></p>\n<h2 id=\"3-使用限制\"><a href=\"#3-%E4%BD%BF%E7%94%A8%E9%99%90%E5%88%B6\" aria-label=\"3 使用限制 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. 使用限制</h2>\n<p>当查询中出现尚未支持的算子、数据类型、文件格式或函数时，引擎会在<strong>生成执行计划的阶段</strong>自动把这部分交还给 原生 Spark 执行，这一机制称为回退（Fallback）。回退后结果保持正确，但在向量化与行式执行的交界处需要做行列格式转换， 因此<strong>如果一条查询中回退的部分过多，整体耗时可能不优于原生 Spark</strong>。建议参考<a href=\"https://cloud.baidu.com/doc/BMR/s/Vmt8jdlx5#6-%E6%9F%A5%E7%9C%8B%E5%9B%9E%E9%80%80%E4%BF%A1%E6%81%AF\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">第6章</a>确认作业的实际回退情况。</p>\n<h3 id=\"31-功能限制\"><a href=\"#31-%E5%8A%9F%E8%83%BD%E9%99%90%E5%88%B6\" aria-label=\"31 功能限制 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3.1 功能限制</h3>\n<table>\n<thead>\n<tr>\n<th>项目</th>\n<th>支持情况</th>\n<th>限制说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>文件格式（读）</td>\n<td>支持（受限）</td>\n<td>仅支持 Parquet、ORC、DWRF。CSV、JSON、Hive 文本表的扫描回退到原生 Spark</td>\n</tr>\n<tr>\n<td>文件格式（写）</td>\n<td>支持（受限）</td>\n<td>仅支持 Parquet。ORC 写入、<code>CREATE TABLE AS SELECT</code>、分桶表写入回退； 不支持 <code>brotli</code>、<code>lzo</code>、<code>lz4raw</code> 压缩编码； BMR 3.5.3（Spark 3.3.2）上原生写入仅覆盖静态分区写入，动态分区写入建议先小范围验证</td>\n</tr>\n<tr>\n<td>ANSI 模式</td>\n<td>不支持</td>\n<td><code>spark.sql.ansi.enabled=true</code> 时整个执行计划回退到原生 Spark</td>\n</tr>\n<tr>\n<td>RDD 作业</td>\n<td>不适用</td>\n<td>向量化仅作用于 Spark SQL 与 DataFrame API，纯 RDD 编写的作业不受益</td>\n</tr>\n<tr>\n<td>Structured Streaming</td>\n<td>不支持</td>\n<td>流式作业不下沉到原生引擎</td>\n</tr>\n<tr>\n<td>Python UDF</td>\n<td>支持（受限）</td>\n<td><code>ArrowEvalPython</code>（普通 Pandas UDF）已向量化； <code>AggregateInPandas</code>、<code>MapInPandas</code>、<code>FlatMapGroupsInPandas</code>、 <code>WindowInPandas</code> 这几类分组 Pandas UDF 不下沉</td>\n</tr>\n<tr>\n<td>Hive UDF / Scala UDF</td>\n<td>支持（受限）</td>\n<td>同一个 Project 中只有 UDF 本身回到 JVM 计算，其余表达式仍在原生引擎执行， 不会因为一个 UDF 导致整段回退</td>\n</tr>\n<tr>\n<td>正则表达式</td>\n<td>支持（受限）</td>\n<td>模式串必须是常量；含 lookahead / lookbehind 的模式回退到原生 Spark。 <code>s</code> 的匹配范围与原生 Spark 略有差异，见本文3.2节</td>\n</tr>\n<tr>\n<td>大小写敏感</td>\n<td>不支持</td>\n<td>开启 <code>spark.sql.caseSensitive=true</code> 时没有回退保护，结果可能与原生 Spark 不一致， 建议保持该参数默认关闭</td>\n</tr>\n<tr>\n<td><code>approx_count_distinct</code></td>\n<td>支持（受限）</td>\n<td>采用与原生 Spark 不同的 HyperLogLog 实现，sketch 二进制格式<strong>不互通</strong>， 不能跨引擎读写 sketch 中间结果</td>\n</tr>\n<tr>\n<td>JSON 字符串格式</td>\n<td>支持（受限）</td>\n<td>JSON 函数只接受双引号字符串，单引号内容会得到非预期结果； <code>get_json_object</code> 对 <code>[*]</code> 形式的路径返回 <code>null</code></td>\n</tr>\n<tr>\n<td>Iceberg</td>\n<td>支持（受限）</td>\n<td>读取已支持；原生写入默认关闭，写入走原生 Spark 路径；含 equality-delete 文件的表读取回退</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"32-结果差异与精度说明\"><a href=\"#32-%E7%BB%93%E6%9E%9C%E5%B7%AE%E5%BC%82%E4%B8%8E%E7%B2%BE%E5%BA%A6%E8%AF%B4%E6%98%8E\" aria-label=\"32 结果差异与精度说明 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3.2 结果差异与精度说明</h3>\n<p>以下差异<strong>不会触发回退、不会报错</strong>。表中的样例与两侧输出全部取自引擎自带的回归测试基线 （与 Spark 3.5 官方预期结果逐条比对得出），可直接复现。</p>\n<p><strong>精度量级</strong>：已确认的数值差异全部出现在 <code>double</code> 类型的浮点聚合上， 差异位于第 16～17 位有效数字，量级为 1 个 ULP（浮点最小精度单位）。 测试基线中<strong>未发现 </strong><code>Decimal</code><strong> 类型的结果差异</strong>，整型的 <code>sum</code>、<code>count</code>、 <code>avg</code> 也未出现差异。若作业对浮点一致性敏感，可将 <code>spark.gluten.sql.columnar.backend.velox.floatingPointMode</code> 设为 <code>strict</code>， 该模式会关闭 <code>sum(float/double)</code> 与 <code>avg(float/double)</code> 的部分聚合刷写。</p>\n<table>\n<thead>\n<tr>\n<th>类别</th>\n<th>场景与样例</th>\n<th>原生 Spark</th>\n<th>向量化引擎</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>精度问题</td>\n<td><code>corr</code> 完全相关时不返回精确 <code>1.0</code></td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td><code>SELECT corr(DISTINCT x, y)FROM (VALUES (1,1),(2,2),(2,2)) t(x,y)</code></td>\n<td><code>1.0</code></td>\n<td><code>0.9999999999999999</code></td>\n<td><strong>不要对 </strong><code>corr</code><strong> 结果做等值判断</strong>，改用误差范围比较</td>\n<td></td>\n</tr>\n<tr>\n<td>精度问题</td>\n<td>统计类聚合末位差异</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td><code>SELECT stddev(a) FROM testData</code></td>\n<td><code>0.8997354108424372</code></td>\n<td><code>0.8997354108424375</code></td>\n<td><code>variance</code>、<code>skewness</code>、<code>kurtosis</code> 属于同类。同一组数据上 <code>skewness</code> 为 <code>-0.2723801058145729</code> 与 <code>-0.27238010581457284</code></td>\n<td></td>\n</tr>\n<tr>\n<td>精度问题</td>\n<td>线性回归函数末位差异</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td><code>SELECT regr_sxx(y, x) FROM testRegression</code></td>\n<td><code>288.6666666666667</code></td>\n<td><code>288.66666666666663</code></td>\n<td><code>regr_r2</code>（<code>0.997690531177829</code> 与 <code>0.9976905311778291</code>）、 <code>regr_slope</code>（<code>0.9988445981121533</code> 与 <code>0.9988445981121532</code>）属于同类</td>\n<td></td>\n</tr>\n<tr>\n<td>算法实现问题</td>\n<td>相同 seed 的随机序列不同</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td><code>SELECT rand(0)</code></td>\n<td><code>0.7604953758285915</code></td>\n<td><code>0.5488135024422883</code></td>\n<td>两者伪随机数实现不同。依赖固定 seed 复现抽样、随机打散或分流的作业会得到<strong>不同的行集合</strong>； 需要严格复现时请关闭向量化执行</td>\n<td></td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"4-适用范围\"><a href=\"#4-%E9%80%82%E7%94%A8%E8%8C%83%E5%9B%B4\" aria-label=\"4 适用范围 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. 适用范围</h2>\n<p>以下支持范围基于 Spark 3.3.2 与 Spark 3.5.5。未列出的格式、类型、算子与函数会回退到原生 Spark 执行。</p>\n<h3 id=\"41-存储格式\"><a href=\"#41-%E5%AD%98%E5%82%A8%E6%A0%BC%E5%BC%8F\" aria-label=\"41 存储格式 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4.1 存储格式</h3>\n<h4 id=\"数据格式\"><a href=\"#%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F\" aria-label=\"数据格式 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>数据格式</h4>\n<table>\n<thead>\n<tr>\n<th>格式</th>\n<th>读取</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Parquet</td>\n<td>支持</td>\n<td>推荐格式。开启 <code>mergeSchema</code> 或读取加密文件时回退</td>\n</tr>\n<tr>\n<td>ORC</td>\n<td>支持</td>\n<td>不支持数组中嵌套结构体或数组、Map 的键为结构体、Map 的值为数组、以及 <code>Timestamp</code> 列； <code>char(n)</code> 类型列默认回退</td>\n</tr>\n<tr>\n<td>DWRF</td>\n<td>支持</td>\n<td>—</td>\n</tr>\n<tr>\n<td>CSV / JSON / 文本</td>\n<td>不支持</td>\n<td>扫描阶段回退到原生 Spark</td>\n</tr>\n</tbody>\n</table>\n<h4 id=\"表格式\"><a href=\"#%E8%A1%A8%E6%A0%BC%E5%BC%8F\" aria-label=\"表格式 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>表格式</h4>\n<table>\n<thead>\n<tr>\n<th>表格式</th>\n<th>读取</th>\n<th>写入</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Hive</td>\n<td>支持</td>\n<td>支持</td>\n<td>写入要求输出格式为 Parquet</td>\n</tr>\n<tr>\n<td>Iceberg</td>\n<td>支持</td>\n<td>不支持</td>\n<td>原生写入默认关闭，写入走原生 Spark；含 equality-delete 文件的表读取回退</td>\n</tr>\n<tr>\n<td>Paimon</td>\n<td>支持</td>\n<td>不支持</td>\n<td>—</td>\n</tr>\n</tbody>\n</table>\n<h4 id=\"存储介质\"><a href=\"#%E5%AD%98%E5%82%A8%E4%BB%8B%E8%B4%A8\" aria-label=\"存储介质 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>存储介质</h4>\n<table>\n<thead>\n<tr>\n<th>介质</th>\n<th>访问方式</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>HDFS</td>\n<td>原生支持，无需额外配置</td>\n</tr>\n<tr>\n<td>BOS</td>\n<td>通过 S3 兼容协议访问，配置沿用 <code>spark.hadoop.fs.s3a.*</code> 系列参数</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"42-数据类型\"><a href=\"#42-%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B\" aria-label=\"42 数据类型 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4.2 数据类型</h3>\n<table>\n<thead>\n<tr>\n<th>支持情况</th>\n<th>数据类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>支持</td>\n<td><code>Boolean</code>、<code>Byte</code>（TinyInt）、<code>Short</code>（SmallInt）、<code>Int</code>、 <code>Long</code>（BigInt）、<code>Float</code>、<code>Double</code>、<code>Decimal</code>（精度与小数位上限 38）、 <code>String</code>、<code>Binary</code>、<code>Date</code>、<code>Timestamp</code>， 以及 <code>Array</code>、<code>Map</code>、<code>Struct</code> 嵌套类型</td>\n</tr>\n<tr>\n<td>不支持</td>\n<td><code>TimestampNTZ</code>（不带时区的时间戳）、<code>Interval Day To Second</code>、 <code>CalendarInterval</code>、用户自定义类型（UDT）、<code>Variant</code></td>\n</tr>\n<tr>\n<td>特殊限制</td>\n<td>聚合算子的<strong>分组列与聚合列不支持 </strong><code>Map</code><strong> 类型</strong>； 查询的输入或输出中只要包含 <code>TimestampNTZ</code>，相关算子即整体回退； <code>Decimal</code> 与 <code>Timestamp</code> 之间的相互转换不支持</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"43-算子\"><a href=\"#43-%E7%AE%97%E5%AD%90\" aria-label=\"43 算子 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4.3 算子</h3>\n<table>\n<thead>\n<tr>\n<th>类型</th>\n<th>支持</th>\n<th>不支持</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>数据源</td>\n<td><code>FileSourceScanExec</code>、<code>HiveTableScanExec</code>、<code>BatchScanExec</code>、 <code>InMemoryTableScanExec</code>、<code>RDDScanExec</code>、<code>RangeExec</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>数据写入</td>\n<td><code>DataWritingCommandExec</code>、<code>WriteFilesExec</code>3.5、 <code>AppendDataExec</code>、<code>ReplaceDataExec</code>、<code>OverwriteByExpressionExec</code>、 <code>OverwritePartitionsDynamicExec</code>、<code>WriteToDataSourceV2Exec</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>通用</td>\n<td><code>ProjectExec</code>、<code>FilterExec</code>、<code>SortExec</code>、<code>UnionExec</code>、 <code>CoalesceExec</code>、<code>ExpandExec</code>、<code>GenerateExec</code></td>\n<td><code>SampleExec</code>（默认关闭）</td>\n</tr>\n<tr>\n<td>聚合</td>\n<td><code>HashAggregateExec</code>、<code>ObjectHashAggregateExec</code>、<code>SortAggregateExec</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>关联</td>\n<td><code>BroadcastHashJoinExec</code>、<code>ShuffledHashJoinExec</code>、<code>SortMergeJoinExec</code>、 <code>BroadcastNestedLoopJoinExec</code>、<code>CartesianProductExec</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>窗口</td>\n<td><code>WindowExec</code>、<code>WindowGroupLimitExec</code>3.5</td>\n<td>—</td>\n</tr>\n<tr>\n<td>数据交换</td>\n<td><code>ShuffleExchangeExec</code>、<code>BroadcastExchangeExec</code>、<code>SubqueryBroadcastExec</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>限流</td>\n<td><code>GlobalLimitExec</code>、<code>LocalLimitExec</code>、<code>TakeOrderedAndProjectExec</code>、 <code>CollectLimitExec</code>、<code>CollectTailExec</code></td>\n<td>带 <code>OFFSET</code> 的排序取前 N 回退</td>\n</tr>\n<tr>\n<td>Python UDF</td>\n<td><code>ArrowEvalPythonExec</code>、<code>BatchEvalPythonExec</code></td>\n<td><code>AggregateInPandasExec</code>、<code>MapInPandasExec</code>、 <code>FlatMapGroupsInPandasExec</code>、<code>WindowInPandasExec</code></td>\n</tr>\n</tbody>\n</table>\n<h4 id=\"算子使用条件\"><a href=\"#%E7%AE%97%E5%AD%90%E4%BD%BF%E7%94%A8%E6%9D%A1%E4%BB%B6\" aria-label=\"算子使用条件 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>算子使用条件</h4>\n<table>\n<thead>\n<tr>\n<th>算子</th>\n<th>条件与限制</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>带 3.5 标记的算子</td>\n<td>由 Spark 3.4 / 3.5 引入，仅在 BMR 3.7.3 及以上（Spark 3.5.5）存在</td>\n</tr>\n<tr>\n<td>数据写入算子</td>\n<td>原生写入仅支持 Parquet；ORC 写入、<code>CREATE TABLE AS SELECT</code>、分桶表写入回退到原生 Spark， 详见 <a href=\"https://cloud.baidu.com/doc/BMR/s/Vmt8jdlx5#3-%E4%BD%BF%E7%94%A8%E9%99%90%E5%88%B6\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">第3章</a></td>\n</tr>\n<tr>\n<td><code>SortMergeJoinExec</code></td>\n<td>支持 Inner、LeftOuter、RightOuter、LeftSemi、LeftAnti；不支持 cross join 与 existence join</td>\n</tr>\n<tr>\n<td><code>BroadcastNestedLoopJoinExec</code></td>\n<td>支持 Inner、LeftOuter、RightOuter、ExistenceJoin；LeftOuter 不能广播左表，RightOuter 不能广播右表</td>\n</tr>\n<tr>\n<td><code>GenerateExec</code></td>\n<td>支持 <code>explode</code>、<code>posexplode</code>、<code>inline</code>、<code>json_tuple</code>、<code>stack</code></td>\n</tr>\n<tr>\n<td><code>WindowGroupLimitExec</code></td>\n<td>窗口 Top-N 下推，仅支持 <code>row_number</code>、<code>rank</code>、<code>dense_rank</code></td>\n</tr>\n<tr>\n<td><code>InMemoryTableScanExec</code></td>\n<td>缓存表以列式格式存储；表结构含不支持的类型时自动降级为原生 Spark 缓存格式</td>\n</tr>\n<tr>\n<td><code>FilterExec</code>、<code>ProjectExec</code></td>\n<td>单个算子中嵌套表达式数量达到 50 时回退</td>\n</tr>\n<tr>\n<td><code>SampleExec</code></td>\n<td>默认关闭，始终回退到原生 Spark</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"44-函数\"><a href=\"#44-%E5%87%BD%E6%95%B0\" aria-label=\"44 函数 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4.4 函数</h3>\n<p>下表以 <strong>Spark 3.3.2 的内建函数清单</strong>为基准统计，这部分函数在两个 BMR 版本上都可用： 标量函数 323 个中<strong>支持 252 个、不支持 71 个</strong>；聚合函数 50 个中<strong>支持 45 个、不支持 5 个</strong>； 窗口函数 9 个与生成器函数 7 个<strong>全部支持</strong>。支持的函数中有一部分带使用条件，在表中以 * 标出。</p>\n<p>带 3.5 标记的函数是 Spark 3.4 / 3.5 新增的，<strong>仅在 BMR 3.7.3 及以上（Spark 3.5.5）可用</strong>， BMR 3.5.3（Spark 3.3.2）本身不提供这些函数。把这部分计入后，Spark 3.5.5 上标量函数支持 268 个、不支持 88 个， 聚合函数支持 52 个、不支持 10 个。</p>\n<table>\n<thead>\n<tr>\n<th>类别</th>\n<th>支持</th>\n<th>不支持</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>数组函数</td>\n<td><code>array</code>、<code>array_append</code>3.5、<code>array_compact</code>3.5、<code>array_contains</code>、<code>array_distinct</code>、<code>array_except</code>、<code>array_insert</code>3.5、<code>array_intersect</code>、<code>array_join</code>、<code>array_max</code>、<code>array_min</code>、<code>array_position</code>、<code>array_prepend</code>3.5、<code>array_remove</code>、<code>array_repeat</code>、<code>array_union</code>、<code>arrays_overlap</code>、<code>arrays_zip</code>、<code>flatten</code>、<code>get</code>、<code>shuffle</code>、<code>slice</code>、<code>sort_array</code></td>\n<td><code>sequence</code></td>\n</tr>\n<tr>\n<td>集合函数</td>\n<td><code>array_size</code>、<code>cardinality</code>、<code>concat</code>、<code>reverse</code>、<code>size</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>位运算函数</td>\n<td><code>&#x26;</code>、<code>|</code>、<code>^</code>、<code>~</code>、<code>bit_count</code>、<code>bit_get</code>、<code>getbit</code>、<code>shiftright</code></td>\n<td></td>\n</tr>\n<tr>\n<td>条件函数</td>\n<td><code>coalesce</code>、<code>if</code>、<code>ifnull</code>、<code>nanvl</code>、<code>nullif</code>、<code>nvl</code>、<code>nvl2</code>、<code>when</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>类型转换函数</td>\n<td><code>bigint</code>、<code>binary</code>、<code>boolean</code>、<code>cast</code>、<code>date</code>、<code>decimal</code>、<code>double</code>、<code>float</code>、<code>int</code>、<code>smallint</code>、<code>string</code>、<code>timestamp</code>、<code>tinyint</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>谓词函数</td>\n<td><code>!</code>、<code>&#x3C;</code>、<code>&#x3C;></code>、<code>></code>、<code>and</code>、<code>between</code>、<code>case</code>、<code>ilike</code>、<code>isnan</code>、<code>isnotnull</code>、<code>isnull</code>、<code>like</code>、<code>not</code>、<code>or</code>、<code>in</code><em>、</em><code>regexp</code>、<code>regexp_like</code><em>、</em><code>rlike</code>**</td>\n<td>—</td>\n</tr>\n<tr>\n<td>哈希函数</td>\n<td><code>crc32</code>、<code>hash</code>、<code>md5</code>、<code>sha</code>、<code>sha1</code>、<code>sha2</code>、<code>xxhash64</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>Map 函数</td>\n<td><code>element_at</code>、<code>map_contains_key</code>、<code>map_entries</code>、<code>map_keys</code>、<code>map_values</code>、<code>map</code><em>、</em><code>map_concat</code>、<code>str_to_map</code>*</td>\n<td><code>map_from_arrays</code>、<code>map_from_entries</code>、<code>try_element_at</code></td>\n</tr>\n<tr>\n<td>结构体函数</td>\n<td><code>named_struct</code>、<code>struct</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>高阶函数</td>\n<td><code>aggregate</code>、<code>array_sort</code>、<code>exists</code>、<code>filter</code>、<code>forall</code>、<code>map_filter</code>、<code>map_zip_with</code>、<code>reduce</code>3.5、<code>transform</code>、<code>transform_keys</code>、<code>transform_values</code>、<code>zip_with</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>数学函数</td>\n<td><code>%</code>、<code>*</code>、<code>+</code>、<code>/</code>、<code>abs</code>、<code>acos</code>、<code>acosh</code>、<code>asin</code>、<code>asinh</code>、<code>atan</code>、<code>atan2</code>、<code>atanh</code>、<code>bin</code>、<code>cbrt</code>、<code>conv</code>、<code>cos</code>、<code>cosh</code>、<code>cot</code>、<code>csc</code>、<code>degrees</code>、<code>div</code>、<code>e</code>、<code>exp</code>、<code>expm1</code>、<code>factorial</code>、<code>greatest</code>、<code>hex</code>、<code>hypot</code>、<code>least</code>、<code>log</code>、<code>log10</code>、<code>log1p</code>、<code>log2</code>、<code>mod</code>、<code>negative</code>、<code>pi</code>、<code>pmod</code>、<code>positive</code>、<code>pow</code>、<code>power</code>、<code>rand</code>、<code>random</code>、<code>rint</code>、<code>round</code>、<code>sec</code>、<code>shiftleft</code>、<code>sign</code>、<code>signum</code>、<code>sinh</code>、<code>sqrt</code>、<code>unhex</code>、<code>width_bucket</code>、<code>ceil</code><em>、</em><code>ceiling</code>、<code>floor</code><em>、</em><code>try_add</code>**</td>\n<td><code>bround</code>、<code>ln</code>、<code>radians</code>、<code>randn</code>、<code>sin</code>、<code>tan</code>、<code>tanh</code>、<code>try_divide</code>、<code>try_multiply</code>、<code>try_subtract</code></td>\n</tr>\n<tr>\n<td>字符串函数</td>\n<td><code>ascii</code>、<code>bit_length</code>、<code>btrim</code>、<code>char</code>、<code>char_length</code>、<code>character_length</code>、<code>chr</code>、<code>concat_ws</code>、<code>find_in_set</code>、<code>initcap</code>、<code>instr</code>、<code>lcase</code>、<code>left</code>、<code>len</code>3.5、<code>length</code>、<code>levenshtein</code>、<code>locate</code>、<code>lower</code>、<code>ltrim</code>、<code>luhn_check</code>3.5、<code>mask</code>3.5、<code>overlay</code>、<code>position</code>、<code>repeat</code>、<code>replace</code>、<code>right</code>、<code>rtrim</code>、<code>soundex</code>、<code>split</code>、<code>split_part</code>、<code>substring_index</code>、<code>translate</code>、<code>trim</code>、<code>ucase</code>、<code>upper</code>、<code>substr</code><em>、</em><code>substring</code>、<code>contains</code><em>、</em><code>endswith</code>、<code>startswith</code><em>、</em><code>lpad</code>、<code>rpad</code><em>、</em><code>regexp_extract</code>、<code>regexp_extract_all</code><em>、</em><code>regexp_replace</code>、<code>base64</code><em>、</em><code>unbase64</code>**</td>\n<td><code>elt</code>、<code>encode</code>、<code>format_number</code>、<code>format_string</code>、<code>octet_length</code>、<code>printf</code>、<code>regexp_count</code>3.5、<code>regexp_instr</code>3.5、<code>regexp_substr</code>3.5、<code>sentences</code>、<code>space</code>、<code>to_binary</code>、<code>to_char</code>3.5、<code>to_number</code>、<code>to_varchar</code>3.5、<code>try_to_binary</code>、<code>try_to_number</code></td>\n</tr>\n<tr>\n<td>日期与时间函数</td>\n<td><code>add_months</code>、<code>date_add</code>、<code>date_diff</code>3.5、<code>date_format</code>、<code>date_from_unix_date</code>、<code>date_sub</code>、<code>date_trunc</code>、<code>dateadd</code>3.5、<code>datediff</code>、<code>day</code>、<code>dayofmonth</code>、<code>dayofweek</code>、<code>dayofyear</code>、<code>extract</code>、<code>from_unixtime</code>、<code>from_utc_timestamp</code>、<code>hour</code>、<code>last_day</code>、<code>make_date</code>、<code>make_timestamp</code>、<code>make_ym_interval</code>、<code>minute</code>、<code>month</code>、<code>months_between</code>、<code>next_day</code>、<code>quarter</code>、<code>second</code>、<code>timestamp_micros</code>、<code>timestamp_millis</code>、<code>to_utc_timestamp</code>、<code>trunc</code>、<code>unix_date</code>、<code>unix_micros</code>、<code>unix_millis</code>、<code>unix_seconds</code>、<code>unix_timestamp</code>、<code>weekday</code>、<code>weekofyear</code>、<code>year</code>、<code>timestamp_seconds</code><em>、</em><code>to_unix_timestamp</code>**</td>\n<td><code>convert_timezone</code>、<code>date_part</code>、<code>datepart</code>3.5、<code>make_dt_interval</code>、<code>make_interval</code>、<code>make_timestamp_ltz</code>、<code>make_timestamp_ntz</code>、<code>session_window</code>、<code>to_timestamp_ltz</code>、<code>to_timestamp_ntz</code>、<code>try_to_timestamp</code>3.5、<code>window</code>、<code>window_time</code>3.5</td>\n</tr>\n<tr>\n<td>JSON 函数</td>\n<td><code>get_json_object</code>、<code>json_array_length</code>、<code>json_object_keys</code>、<code>json_tuple</code>、<code>from_json</code><em>、</em><code>to_json</code>**</td>\n<td><code>schema_of_json</code></td>\n</tr>\n<tr>\n<td>URL 函数</td>\n<td><code>url_decode</code>3.5、<code>url_encode</code>3.5</td>\n<td><code>parse_url</code></td>\n</tr>\n<tr>\n<td>CSV 函数</td>\n<td>—</td>\n<td><code>from_csv</code>、<code>schema_of_csv</code>、<code>to_csv</code></td>\n</tr>\n<tr>\n<td>XML 函数</td>\n<td>—</td>\n<td><code>xpath</code>、<code>xpath_boolean</code>、<code>xpath_double</code>、<code>xpath_float</code>、<code>xpath_int</code>、<code>xpath_long</code>、<code>xpath_number</code>、<code>xpath_short</code>、<code>xpath_string</code></td>\n</tr>\n<tr>\n<td>其他函数</td>\n<td><code>assert_true</code>、<code>equal_null</code>3.5、<code>spark_partition_id</code>、<code>uuid</code>、<code>version</code>、<code>|</code></td>\n<td></td>\n</tr>\n<tr>\n<td>聚合函数</td>\n<td><code>any</code>、<code>any_value</code>3.5、<code>approx_count_distinct</code>、<code>array_agg</code>、<code>avg</code>、<code>bit_and</code>、<code>bit_or</code>、<code>bit_xor</code>、<code>bool_and</code>、<code>bool_or</code>、<code>collect_list</code>、<code>collect_set</code>、<code>corr</code>、<code>count</code>、<code>count_if</code>、<code>covar_pop</code>、<code>covar_samp</code>、<code>every</code>、<code>first</code>、<code>first_value</code>、<code>grouping</code>、<code>grouping_id</code>、<code>kurtosis</code>、<code>last</code>、<code>last_value</code>、<code>max</code>、<code>max_by</code>、<code>mean</code>、<code>median</code>3.5、<code>min</code>、<code>min_by</code>、<code>regr_avgx</code>、<code>regr_avgy</code>、<code>regr_count</code>、<code>regr_intercept</code>3.5、<code>regr_r2</code>、<code>regr_slope</code>3.5、<code>regr_sxx</code>3.5、<code>regr_sxy</code>3.5、<code>regr_syy</code>3.5、<code>skewness</code>、<code>some</code>、<code>std</code>、<code>stddev</code>、<code>stddev_pop</code>、<code>stddev_samp</code>、<code>sum</code>、<code>try_avg</code>、<code>var_pop</code>、<code>var_samp</code>、<code>variance</code>、<code>try_sum</code>*</td>\n<td><code>approx_percentile</code>、<code>bitmap_construct_agg</code>3.5、<code>bitmap_or_agg</code>3.5、<code>count_min_sketch</code>、<code>histogram_numeric</code>、<code>hll_sketch_agg</code>3.5、<code>hll_union_agg</code>3.5、<code>mode</code>3.5、<code>percentile</code>、<code>percentile_approx</code></td>\n</tr>\n<tr>\n<td>窗口函数</td>\n<td><code>cume_dist</code>、<code>dense_rank</code>、<code>lag</code>、<code>lead</code>、<code>nth_value</code>、<code>ntile</code>、<code>percent_rank</code>、<code>rank</code>、<code>row_number</code></td>\n<td>—</td>\n</tr>\n<tr>\n<td>生成器函数</td>\n<td><code>explode</code>、<code>explode_outer</code>、<code>inline</code>、<code>inline_outer</code>、<code>posexplode</code>、<code>posexplode_outer</code>、<code>stack</code></td>\n<td>—</td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"5-开启与关闭\"><a href=\"#5-%E5%BC%80%E5%90%AF%E4%B8%8E%E5%85%B3%E9%97%AD\" aria-label=\"5 开启与关闭 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5. 开启与关闭</h2>\n<h3 id=\"51-默认已开启\"><a href=\"#51-%E9%BB%98%E8%AE%A4%E5%B7%B2%E5%BC%80%E5%90%AF\" aria-label=\"51 默认已开启 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5.1 默认已开启</h3>\n<p>BMR 集群已在 <code>spark-defaults.conf</code> 中预置以下配置，向量化执行<strong>默认生效，您无需做任何操作</strong>。</p>\n<table>\n<thead>\n<tr>\n<th>配置项</th>\n<th>值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>spark.plugins</code></td>\n<td><code>org.apache.gluten.GlutenPlugin</code></td>\n</tr>\n<tr>\n<td><code>spark.shuffle.manager</code></td>\n<td><code>org.apache.spark.shuffle.sort.ColumnarShuffleManager</code></td>\n</tr>\n<tr>\n<td><code>spark.memory.offHeap.enabled</code></td>\n<td><code>true</code></td>\n</tr>\n<tr>\n<td><code>spark.memory.offHeap.size</code></td>\n<td>按 <a href=\"https://cloud.baidu.com/doc/BMR/s/Vmt8jdlx5#52-%E5%86%85%E5%AD%98%E9%85%8D%E7%BD%AE%E5%BB%BA%E8%AE%AE\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">5.2</a> 设置</td>\n</tr>\n</tbody>\n</table>\n<p>前两项是引擎的加载入口，<strong>不建议修改</strong>。如需关闭向量化执行，请使用<a href=\"https://cloud.baidu.com/doc/BMR/s/Vmt8jdlx5#53-%E5%85%B3%E9%97%AD%E6%96%B9%E5%BC%8F\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">5.3节</a>的开关，而不是删除这两项配置。</p>\n<h3 id=\"52-内存配置建议\"><a href=\"#52-%E5%86%85%E5%AD%98%E9%85%8D%E7%BD%AE%E5%BB%BA%E8%AE%AE\" aria-label=\"52 内存配置建议 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5.2 内存配置建议</h3>\n<p>向量化执行的计算过程全部在堆外内存进行，因此需要为 Executor 配置堆外内存。推荐比例为 <strong>每 1 个 CPU 核配置 1 GB </strong><code>executor.memory</code><strong> 与 2 GB </strong><code>offHeap.size</code>。</p>\n<p>此外，<code>spark.executor.memoryOverhead</code> 若未显式设置，会被自动调整为 <code>max(0.3 × offHeap.size, 384 MiB)</code>。做容量规划时需要把这部分一并算入，否则容易因为 Executor 总内存超出申请值而被 YARN 终止。</p>\n<table>\n<thead>\n<tr>\n<th>Executor 核数</th>\n<th><code>spark.executor.memory</code></th>\n<th><code>spark.memory.offHeap.size</code></th>\n<th>自动调整的 <code>memoryOverhead</code></th>\n<th>单 Executor 实际占用</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>2</td>\n<td>2 GB</td>\n<td>4 GB</td>\n<td>1.2 GB</td>\n<td>约 7.2 GB</td>\n</tr>\n<tr>\n<td>4</td>\n<td>4 GB</td>\n<td>8 GB</td>\n<td>2.4 GB</td>\n<td>约 14.4 GB</td>\n</tr>\n<tr>\n<td>8</td>\n<td>8 GB</td>\n<td>16 GB</td>\n<td>4.8 GB</td>\n<td>约 28.8 GB</td>\n</tr>\n</tbody>\n</table>\n<p><strong>注意</strong>：<code>spark.memory.offHeap.enabled</code> 为 <code>false</code>，或 <code>spark.memory.offHeap.size</code> 小于 1 MB 时，作业会在 Driver 启动阶段直接失败。 如果您需要完全不使用堆外内存，请先按<a href=\"https://cloud.baidu.com/doc/BMR/s/Vmt8jdlx5#53-%E5%85%B3%E9%97%AD%E6%96%B9%E5%BC%8F\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">5.3节</a>关闭向量化执行。</p>\n<h3 id=\"53-关闭方式\"><a href=\"#53-%E5%85%B3%E9%97%AD%E6%96%B9%E5%BC%8F\" aria-label=\"53 关闭方式 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5.3 关闭方式</h3>\n<p>关闭后对应部分回落到原生 Spark 的行式执行，<strong>查询结果不变</strong>。三种生效途径任选其一：</p>\n<table>\n<thead>\n<tr>\n<th>途径</th>\n<th>生效范围</th>\n<th>操作</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>修改集群配置</td>\n<td>集群上所有作业</td>\n<td>在控制台的配置管理中修改 <code>spark-defaults.conf</code>，添加或调整对应配置项</td>\n</tr>\n<tr>\n<td>提交作业时覆盖</td>\n<td>仅本次作业</td>\n<td><code>spark-submit --conf spark.gluten.enabled=false ...</code></td>\n</tr>\n<tr>\n<td>会话中动态设置</td>\n<td>仅当前会话</td>\n<td>在 <code>spark-sql</code> 中执行 <code>SET spark.gluten.enabled=false;</code></td>\n</tr>\n</tbody>\n</table>\n<h4 id=\"可用开关\"><a href=\"#%E5%8F%AF%E7%94%A8%E5%BC%80%E5%85%B3\" aria-label=\"可用开关 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>可用开关</h4>\n<table>\n<thead>\n<tr>\n<th>配置项</th>\n<th>默认值</th>\n<th>作用</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>spark.gluten.enabled</code></td>\n<td><code>true</code></td>\n<td><strong>总开关</strong>。设为 <code>false</code> 后整个作业完全使用原生 Spark 执行</td>\n</tr>\n<tr>\n<td><code>spark.plugins</code></td>\n<td><code>org.apache.gluten.GlutenPlugin</code></td>\n<td>向量化引擎加载Plugin。<strong>移除配置</strong>后可彻底关闭向量化引擎初始化</td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"6-查看回退信息\"><a href=\"#6-%E6%9F%A5%E7%9C%8B%E5%9B%9E%E9%80%80%E4%BF%A1%E6%81%AF\" aria-label=\"6 查看回退信息 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>6. 查看回退信息</h2>\n<p>作业是否真正走了向量化执行、哪些算子发生了回退，都可以在 Spark UI 中直接查看，无需额外配置或改代码。 打开 Spark UI 后切换到 <strong>Gluten SQL / DataFrame</strong> 页签即可。</p>\n<table>\n<thead>\n<tr>\n<th>页面元素</th>\n<th>含义</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Num Gluten Nodes</td>\n<td>该查询中成功下沉到原生引擎执行的算子数量，数值越大说明向量化覆盖越充分</td>\n</tr>\n<tr>\n<td>Num Fallback Nodes</td>\n<td>回退到原生 Spark 执行的算子数量，为 0 表示全程向量化</td>\n</tr>\n<tr>\n<td><code>+details</code> 展开</td>\n<td>显示 <code>== Fallback Summary ==</code> 块，逐行给出 <code>(算子编号) 算子名: 回退原因</code>； 若该查询全程向量化，则显示 <code>No fallback nodes</code></td>\n</tr>\n<tr>\n<td>页签内的版本信息</td>\n<td>展示当前使用的 Apache Gluten 与 Velox 版本</td>\n</tr>\n</tbody>\n</table>\n<p><img src=\"https://bce.bdstatic.com/doc/bce-doc/BMR/k2_71d2c97.png\" alt=\"k2.png\">\n如果发现回退节点数偏多，可结合<a href=\"https://cloud.baidu.com/doc/BMR/s/Vmt8jdlx5#3-%E4%BD%BF%E7%94%A8%E9%99%90%E5%88%B6\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">第3章</a>的限制清单排查原因，常见情况是表使用了 CSV / JSON / 文本格式、查询开启了 ANSI 模式、或使用了尚未支持的函数。</p>","fields":{"slug":"Vmt8jdlx5","title":"Spark向量化","date":"2026-08-25","extractedHeadings":[]},"headings":[{"value":"1. 概述","depth":2},{"value":"1.1 支持的版本","depth":3},{"value":"1.2 性能表现","depth":3},{"value":"2. 原理介绍","depth":2},{"value":"3. 使用限制","depth":2},{"value":"3.1 功能限制","depth":3},{"value":"3.2 结果差异与精度说明","depth":3},{"value":"4. 适用范围","depth":2},{"value":"4.1 存储格式","depth":3},{"value":"数据格式","depth":4},{"value":"表格式","depth":4},{"value":"存储介质","depth":4},{"value":"4.2 数据类型","depth":3},{"value":"4.3 算子","depth":3},{"value":"算子使用条件","depth":4},{"value":"4.4 函数","depth":3},{"value":"5. 开启与关闭","depth":2},{"value":"5.1 默认已开启","depth":3},{"value":"5.2 内存配置建议","depth":3},{"value":"5.3 关闭方式","depth":3},{"value":"可用开关","depth":4},{"value":"6. 查看回退信息","depth":2}]}},"pageContext":{"isCreatedByStatefulCreatePages":false,"slug":"Vmt8jdlx5","prev":{"id":"hm692zot3","name":"基础使用","path":"hm692zot3","filePath":"开源组件介绍/Spark/基础使用.md","seo":null,"parentIds":["ejwvxvcqb","vm692zcut"],"parents":[{"id":"ejwvxvcqb","documentId":null,"name":"开源组件介绍","repoName":"BMR","filePath":"开源组件介绍","disabled":false,"path":"ejwvxvcqb","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":null},{"id":"vm692zcut","documentId":"580cee07-6379-4c7d-8e18-2f983ef497c3","name":"Spark","repoName":"BMR","filePath":"开源组件介绍/Spark","disabled":false,"path":"vm692zcut","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":null}]},"next":{"id":"8mrwyv9ix","name":"Spark SQL防御","path":"8mrwyv9ix","filePath":"开源组件介绍/Spark/Spark SQL防御.md","seo":null,"parentIds":["ejwvxvcqb","vm692zcut"],"parents":[{"id":"ejwvxvcqb","documentId":null,"name":"开源组件介绍","repoName":"BMR","filePath":"开源组件介绍","disabled":false,"path":"ejwvxvcqb","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":null},{"id":"vm692zcut","documentId":"580cee07-6379-4c7d-8e18-2f983ef497c3","name":"Spark","repoName":"BMR","filePath":"开源组件介绍/Spark","disabled":false,"path":"vm692zcut","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":null}]},"parents":[{"id":"ejwvxvcqb","documentId":null,"name":"开源组件介绍","repoName":"BMR","filePath":"开源组件介绍","disabled":false,"path":"ejwvxvcqb","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":null},{"id":"vm692zcut","documentId":"580cee07-6379-4c7d-8e18-2f983ef497c3","name":"Spark","repoName":"BMR","filePath":"开源组件介绍/Spark","disabled":false,"path":"vm692zcut","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":null}],"specificSeo":null}}}