upper和lower仅用于字符串大小写转换,不实现大小写不敏感查询;真正起作用的是数据库排序规则(collation)或显式指定collation,优先检查字段是否已设为_ci后缀的不敏感规则。

直接说结论:UPPER 和 LOWER 本身不解决大小写不敏感查询,它们只是转换字符串的工具;真正决定是否大小写不敏感的是数据库的排序规则(collation)或显式转换后比对。
为什么 UPPER/LOWER 在 WHERE 中常被误用
很多人以为写 WHERE UPPER(name) = UPPER('alice') 就是“大小写不敏感查询”,其实这只是强制统一成大写再比对——它能工作,但代价高、可读差、且可能绕过索引。真正该优先检查的是字段本身的 collation 是否已设为 utf8mb4_unicode_ci(MySQL)或 SQL_Latin1_General_CP1_CI_AS(SQL Server)这类带 _CI(case-insensitive)后缀的规则。
- 如果 collation 已是大小写不敏感,
WHERE name = 'Alice'就自动匹配'alice'、'ALICE'等 - 如果 collation 是
_CS(case-sensitive),才需要考虑转换函数或临时指定 collation -
UPPER()和LOWER()在 WHERE 子句中会使字段无法走索引(除非建了函数索引)
MySQL 中正确使用 UPPER/LOWER 的典型场景
适用于 collation 强制区分大小写,又不想改表结构时的临时方案;注意必须两端都转换,否则无效。
- 安全写法:
WHERE UPPER(name) = UPPER('Alice')或WHERE LOWER(name) = LOWER('Alice') - 避免只转一边:
WHERE UPPER(name) = 'alice'会漏掉原始为小写的记录(因为UPPER('alice')是'ALICE') - 如需索引加速,MySQL 8.0+ 可建函数索引:
CREATE INDEX idx_name_upper ON users (UPPER(name)); - 注意字符集兼容性:
UPPER()对中文、数字无影响,但某些特殊字符(如德语 ß)在不同 collation 下行为不同
PostgreSQL 和 SQL Server 的更优替代方案
它们提供了原生大小写不敏感比较操作符,比硬套 UPPER/LOWER 更清晰、更易优化。
- PostgreSQL 推荐用
ILIKE:WHERE name ILIKE 'alice',支持通配符且通常能用索引(配合text_pattern_ops) - SQL Server 推荐用
COLLATE指定临时规则:WHERE name COLLATE SQL_Latin1_General_CP1_CI_AS = 'Alice' - SQL Server 也支持
LIKE配合COLLATE实现模糊匹配:WHERE name COLLATE Latin1_General_CI_AI LIKE '%alice%' - 这些方式比
UPPER(name) = UPPER('...')更易读,优化器也更容易识别意图
容易被忽略的边界问题
大小写转换不是纯数学映射,尤其在多语言环境下。
- 土耳其语中,小写
i的大写是İ(带点),而非I;默认UPPER()可能出错,需确认数据库 locale 设置 - Unicode 扩展字符(如带重音符号的 é、ñ)在部分旧 collation 下可能被错误归类,
LOWER()后比较仍不等价 - 空值(
NULL)经UPPER(NULL)仍为NULL,和任何值比较结果都是UNKNOWN,记得加IS NOT NULL判断 - 函数调用开销虽小,但在大数据量 JOIN 或子查询中累积明显,优先查 collation,其次用原生语法,最后才用
UPPER/LOWER











