跳转到主内容
极星编程网:以代码为星,赴技术山海!

如何进行字符串拼接_管道符||与CONCAT函数性能对比

MySQL中||默认是逻辑或而非字符串拼接,需启用PIPES_AS_CONCAT模式;CONCAT遇NULL返回NULL,CONCAT_WS跳过NULL;跨库兼容推荐CONCAT但需处理NULL差异。 MySQL 里用
||
拼字符串,为什么结果是 0 或 NULL? 因为默认情况下,mysql 的
||
不是字符串拼接,而是逻辑或运算符。只有当 sql 模式启用了
pipes_as_concat
,
||
才等价于
concat()
。 常见错误现象:
SELECT 'a' || 'b';
返回
0
(两个非空字符串转布尔都是 TRUE,TRUE OR TRUE = 1?不对——实际是先转数字失败→0),或者在严格模式下直接报错。 检查当前模式:
SELECT @@sql_mode;
,看是否含
PIPES_AS_CONCAT
临时启用(当前会话):
SET sql_mode = CONCAT(@@sql_mode, ',PIPES_AS_CONCAT');
不推荐全局改,尤其在多应用共用实例时,可能破坏依赖标准行为的旧逻辑
CONCAT()
和
CONCAT_WS()
的 NULL 处理差异
CONCAT()
遇到任意参数为
NULL
,整条结果就变成
NULL
;而
CONCAT_WS()
(WS = With Separator)只跳过
NULL
参数,不影响其余部分。 使用场景:拼接用户姓名字段,
middle_name
可能为空,用
CONCAT(first, ' ', middle, ' ', last)
一空全空;换成
CONCAT_WS(' ', first, middle, last)
就自然省略空段。
CONCAT('a', NULL, 'c')
→
NULL
CONCAT_WS('-', 'a', NULL, 'c')
→
'a-c'
CONCAT_WS()
的第一个参数是分隔符,不能为
NULL
,否则整个结果为
NULL
性能上
||
真的比
CONCAT()
快吗? 在启用了
PIPES_AS_CONCAT
的前提下,两者执行计划、底层处理路径几乎一致,性能差异可忽略——不是语法糖快,是“根本没额外开销”。真正影响性能的是拼接内容本身:字段长度、字符集转换、是否触发隐式类型转换。 容易踩的坑:
CONCAT(id, name)
中
id
是 INT,MySQL 会把整行记录的
name
字段也转成 same charset + collation 再拼,若
name
是 utf8mb4 而连接默认字符集是 latin1,就会悄悄触发转换,拖慢查询。 显式转码更可控:
CONCAT(CAST(id AS CHAR), name)
避免混合数值与字符串直接拼接,尤其在 WHERE 或 ORDER BY 中参与计算时 高并发拼接长文本(如日志聚合)时,优先考虑应用层做,别压给 MySQL 字符串函数 PostgreSQL / Oracle / SQL Server 怎么看? 别套用 MySQL 经验:
||
在 PostgreSQL 和 Oracle 中原生就是字符串拼接,无需设模式;SQL Server 则完全不支持
||
,必须用
+
(且对
NULL
更敏感)或
CONCAT()
(SQL Server 2012+)。 跨数据库写法最稳的是
CONCAT()
,但要注意:MySQL
CONCAT()
不接受
NULL
,而 SQL Server 和 PostgreSQL 的
CONCAT()
会自动跳过
NULL
—— 同一个函数,在不同库行为不一致。 MySQL:
CONCAT(NULL, 'a')
→
NULL
SQL Server:
CONCAT(NULL, 'a')
→
'a'
真要移植,要么统一用
COALESCE(col, '')
做兜底,要么干脆别拼,让应用层处理 字符集、NULL 行为、跨库兼容性这三块,改一行拼接代码就可能漏掉两处隐式陷阱。

相关文章