唯一安全且推荐的用法是在select中使用upper()/lower()格式化输出,不改原数据、不干扰索引、对null安全、兼容所有主流数据库,非字母字符保持不变。

直接在 SELECT 里用 UPPER() 或 LOWER() 就行,这是唯一安全、无副作用、不拖慢查询的做法。
SELECT 中用 UPPER()/LOWER() 只是格式化输出
它不改原数据、不干扰索引、对 NULL 安全,且所有主流数据库(MySQL 8.0+、PostgreSQL、SQL Server、Oracle、SQLite)都支持。
-
UPPER(name)把字段值转成全大写展示,LOWER(email)同理转小写 - 非字母字符(数字、中文、emoji、标点、空格)原样保留:
UPPER('café你好123!')→'CAFÉ你好123!' - 别名必须显式加:
SELECT UPPER(first_name) AS first_name, email FROM users,否则和原始字段同名会冲突 - 可嵌套使用,但顺序影响结果:想拼接后统一转大写,写
UPPER(CONCAT(first_name, ' ', last_name));若先各自转再拼,空格仍是小写
WHERE 条件里裸用 UPPER() 会触发全表扫描
比如 WHERE UPPER(email) = 'JOE@EXAMPLE.COM' 看似方便,但数据库无法利用 email 列上已有的索引——因为索引存的是原始值,函数计算结果无法反向映射。
- 百万级表上,响应可能从几毫秒变成几秒
- MySQL 8.0+ 和 PostgreSQL 支持函数索引,但必须手动建:
CREATE INDEX idx_email_upper ON users (UPPER(email)) - 更稳妥的方案是入库时就标准化:
INSERT INTO users (email) VALUES (LOWER(?)),查时直接WHERE email = 'joe@example.com' - SQLite 不支持函数索引,只能靠
COLLATE NOCASE或入库存小写
ORDER BY 和 GROUP BY 中用大小写函数代价高
比如 GROUP BY LOWER(tag),数据库得先把每行 tag 都算一遍小写,再分组——大数据量下内存和 CPU 开销明显。
- 真正控制排序行为的是 collation,不是函数:
ORDER BY tag COLLATE utf8mb4_bin比ORDER BY LOWER(tag)更快更可控 - PostgreSQL 中
ORDER BY LOWER(name) NULLS LAST必须显式写NULLS LAST,否则NULL默认排最前 - 高频聚合场景建议加计算列:
ALTER TABLE posts ADD COLUMN tag_lower VARCHAR(50) GENERATED ALWAYS AS (LOWER(tag)) STORED,再对tag_lower建普通索引
最容易被忽略的不是函数怎么写,而是数据写入那一刻有没有做大小写标准化——函数只是补救手段,不是设计替代品。










