ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

StarRocks LENGTH 函数详解:字节长度语义、源码实现与多语言实战

StarRocks LENGTH 函数详解:字节长度语义、源码实现与多语言实战 StarRocks LENGTH 函数详解字节长度语义、源码实现与多语言实战【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks本文以 StarRocks 官方文档 length 为核心深入讲解length字符串函数的语法、返回值语义按字节计算与典型使用场景并结合 BE 端向量化执行源码与单元测试说明其底层实现原理与边界行为。读完本文你将掌握length与字符计数类函数的区别并能正确应用于数据校验、字段截断、分区裁剪等实战场景。函数概述length是 StarRocks 中最常用的字符串函数之一用于返回字符串的字节长度byte length返回类型为INT。它对应的官方函数说明位于 docs/en/sql-reference/sql-functions/string-functions/length.md。需要特别强调的是length统计的是字节数而非字符数。对于纯 ASCII 字符串字节数与字符数相等一旦字符串中包含中文、日文、emoji 等多字节 UTF-8 字符两者的结果就会产生差异。这是使用该函数时最容易踩的坑也是本文重点辨析的内容。语法与返回值语法定义INT length(VARCHAR str)参数strVARCHAR 类型的字符串表达式也兼容 CHAR、STRING 等字符串类型。返回值INT表示输入字符串占用的字节数。入参为NULL时返回NULL。官方示例在 MySQL 客户端中执行MySQL select length(abc); --------------- | length(abc) | --------------- | 3 | ---------------abc为 3 个 ASCII 字符每个字符占 1 字节因此字节长度为3。字节长度 vs 字符长度多字节字符串的差异对包含多字节 UTF-8 编码字符的字符串length返回的字节数会明显大于“肉眼可见”的字符数。这是由 UTF-8 变长编码决定的一个中文字符通常占 3 个字节emoji 等字符可能占 4 字节。下表对比了常见字符串在length字节数下的结果输入字符串可见字符数length 返回的字节数abc33中文26中文03714示例验证SELECT length(中文); -- 返回 6 SELECT length(中文0); -- 返回 7 SELECT length(); -- 返回 4需要字符长度时怎么办如果业务上需要统计字符数而不是字节数StarRocks 提供了char_length/character_length函数两者按 UTF-8 字符边界计数。例如SELECT char_length(中文); -- 返回 2 SELECT char_length(); -- 返回 1在 StarRocks 中char_length的语义与 utf8_length 相对应按 UTF-8 字符统计而length的语义与 length按字节统计相对应。使用时务必根据需求区分避免多字节字符场景下统计口径出错。源码实现向量化执行下的底层原理length在 BEBackend端是一个向量化字符串函数实现在 be/src/exprs/string_functions.cpp// length DEFINE_UNARY_FN_WITH_IMPL(lengthImpl, str) { return str.size; } StatusOrColumnPtr StringFunctions::length(FunctionContext* context, const Columns columns) { return VectorizedStrictUnaryFunctionlengthImpl::evaluateTYPE_VARCHAR, TYPE_INT(columns[0]); }从源码结构可以看出三点核心事实实现极其轻量lengthImpl直接返回str.size即二进制字符串占用的字节数。由于 StarRocks 的字符串列以BinaryColumn偏移量 连续字节缓冲区存储字符串长度可以直接从切片大小获得无需扫描字符内容因此该函数几乎零开销。向量化执行通过VectorizedStrictUnaryFunctionlengthImpl::evaluateTYPE_VARCHAR, TYPE_INT对整列进行批量求值输入类型为TYPE_VARCHAR输出类型为TYPE_INT。这与 StarRocks 的 SIMD 向量化执行引擎一脉相承适合在数百万行的列上批量计算。严格单目函数VectorizedStrictUnaryFunction表示该函数是“严格”的——输入为NULL时结果直接为NULL不进入lengthImpl保证了length(NULL) NULL的语义。与之对应的 utf8_length同文件中的 utf8_length 则通过utf8_len(str.data, str.data str.size)遍历字符串并按 UTF-8 编码边界计数这正是char_length的底层实现也是它比length略“重”的原因。单元测试验证BE 端针对该函数编写了专门的向量化单测位于 be/test/exprs/string_fn_test.cpp覆盖了纯数字、ASCII 与中文混排等场景测试用例输入断言结果说明lengthTest0~9、10~191、2ASCII 数字的字节长度lengthChineseTest中文0~中文9、中文10~中文197、8中文字符按 3 字节计中文占 6 字节utf8LengthTest同上1、2字符计数视角utf8LengthChineseTest同上3、4中文按 2 个字符计例如lengthChineseTest中输入中文 数字中文 为 6 字节一位数字 1 字节分别得到 7 和 8与 UTF-8 字节计算规则完全吻合。这些测试用例可在run-be-ut.sh脚本体系下直接运行验证。实战使用场景1. 字段长度校验与清洗在数据导入或 ETL 过程中常用length校验字段是否超长、是否为空串-- 找出空字符串注意空串长度 0与 NULL 不同 SELECT * FROM user_profile WHERE length(nickname) 0; -- 找出超长字段如手机号异常 SELECT * FROM user_profile WHERE length(phone) 11;2. 与截断函数配合使用length常与left、right、substr等截断函数组合例如按字节截断字段以保证写入目标表不超限-- 只保留前 10 个字节可用于 ASCII 定长字段裁剪 SELECT left(comment, 10) FROM feedback;3. 分组统计与聚合作为标量表达式length可以出现在聚合、过滤、排序等任意位置-- 按评论长度分桶统计 SELECT length(comment) AS len, count(*) AS cnt FROM feedback GROUP BY length(comment) ORDER BY len;4. 结合常量折叠优化从 fe-core 优化器 等源码结构可以推断length等确定性内置函数在 FE 优化阶段可参与常量折叠constant folding对WHERE length(abc) 3这类条件表达式会在执行前被预计算为常量从而进一步减少执行开销。使用注意事项计数单位是字节涉及中文、emoji 等多字节字符时length结果不等于字符数需要字符数请使用char_length/character_length。空串与 NULL 的区分length()返回0而length(NULL)返回NULL在 WHERE 条件中需要用IS NULL分别判断。返回类型为 INTStarRocks 中VARCHAR长度上限为 1048576 字节受get_olap_string_max_length()约束参见 be/src/exprs/string_functions.cpp 附近的字符串长度上限检查INT 类型足以容纳无需担心溢出。与 MySQL 语义一致StarRocks 的length与 MySQL 的length()行为一致均返回字节数熟悉 MySQL 的用户可以无缝迁移。相关函数与延伸阅读char_length / character_length返回字符数UTF-8 字符计数。octet_length部分方言中与length等价均为字节数。其他字符串函数substr、concat、replace等的向量化实现同样位于 be/src/exprs/string_functions.cpp测试集中在 be/test/exprs/string_fn_test.cpp可一并查阅。小结length是 StarRocks 字符串函数体系中返回字节长度的基础函数语法简单、实现轻量、执行向量化单测覆盖充分。理解其“按字节计数”的核心语义并与char_length按字符计数区分开是写出正确查询的前提。对追求性能的场景由于其底层仅读取切片大小即使在大宽表、亿级行上批量调用也几乎不产生额外开销。【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表