MySQL中LENGTH()返回字节数而非字符数,utf8mb4下汉字占3-4字节,需用CHAR_LENGTH()按字符过滤;PostgreSQL中LENGTH()按字符计,OCTET_LENGTH()才按字节;SQL Server用LEN()和DATALENGTH()区分字符与字节。

MySQL里用LENGTH()查超长文本,注意字符集陷阱
MySQL的LENGTH()返回的是字节数,不是字符数。如果你的字段是utf8mb4(比如存emoji或中文),一个汉字可能占3或4个字节,直接拿LENGTH(content) > 100当“超过100个字符”用,结果会偏少——实际内容可能才60个汉字就触发了。
- 确认字段字符集:
SHOW CREATE TABLE your_table;看content列的CHARSET和COLLATION - 想按字符数过滤,改用
CHAR_LENGTH()更安全,它统计的是Unicode字符个数 - 如果必须用
LENGTH()(比如做存储空间估算),得先知道最大单字符字节数:utf8mb4下最多4字节,所以“字符数≥100”的等价条件是LENGTH(content) > 400
PostgreSQL中LENGTH()行为不同,别套用MySQL经验
PostgreSQL的LENGTH()默认按字符计数,和MySQL的LENGTH()语义相反,但和MySQL的CHAR_LENGTH()一致。直接迁移SQL时容易翻车。
- PostgreSQL里
LENGTH(content) > 100就是“字符数超过100”,没问题 - 如果要按字节查(比如排查BLOB混入),得用
OCTET_LENGTH(content) - 注意空格和不可见字符:
LENGTH('a' || E'\t' || 'b')在PG里返回3,含制表符;若业务上想忽略首尾空白,先TRIM()再算
WHERE子句里用LENGTH()可能拖慢查询,小心索引失效
对字段套函数后,绝大多数数据库无法走索引。哪怕content上有索引,WHERE LENGTH(content) > 500也会触发全表扫描。
- 高频查询超长文本?考虑加生成列+索引(MySQL 5.7+):
ALTER TABLE t ADD COLUMN content_len INT AS (CHAR_LENGTH(content)) STORED;,再给content_len建索引 - PostgreSQL可用函数索引:
CREATE INDEX idx_content_len ON t ((LENGTH(content))); - 临时排查可以,线上查询量大时避免裸用
LENGTH()在WHERE里
SQL Server用LEN()和DATALENGTH()区分更明显
SQL Server不叫LENGTH(),LEN()去尾空格后计字符数,DATALENGTH()返回字节数——两者差值可能很大,尤其遇到nvarchar(Unicode,每字符2字节)。
-
LEN(N'你好')返回2,DATALENGTH(N'你好')返回4 - 查“实际存储超过1KB的文本”,必须用
DATALENGTH(content) > 1024,用LEN()会错判 -
LEN()对varchar和nvarchar都适用,但结果含义不同:前者是字节数近似值(ASCII下=字符数),后者才是真实字符数

















