LIKE通配符放在模式开头(如'%abc')性能最差,因B-Tree索引完全失效;嵌套查询中子查询返回NULL会导致WHERE条件不成立,返回空结果;REGEXP虽表达力强但无法索引优化,性能风险更高;参数化查询须由应用层添加通配符,禁止SQL内拼接。

LIKE 通配符放哪儿性能最差?
放在 LIKE 模式开头(如 '%abc')会让索引完全失效,尤其在大表上查得慢到像卡住。MySQL、PostgreSQL 都一样,不是语法问题,是 B-Tree 索引天生不支持前缀模糊。
- 能用
'abc%'就别用'%abc'—— 这样还能走索引 - 真要查后缀?考虑加反向索引(
REVERSE(column)+ 函数索引)或全文索引 - PostgreSQL 可用
pg_trgm扩展加速任意位置匹配,但需提前建GIN索引
嵌套查询里写 LIKE 容易漏掉什么?
子查询结果如果含 NULL,外层 WHERE column LIKE (SELECT ...) 会直接返回空——因为 NULL LIKE 'xxx' 结果是 UNKNOWN,不进 WHERE 条件。
- 务必用
COALESCE或显式过滤:比如WHERE column LIKE COALESCE((SELECT pattern FROM config), '%') - 子查询返回多行?
LIKE不支持,会报错Subquery returns more than 1 row,改用EXISTS或IN+JOIN - 注意字符集:若字段是
utf8mb4而子查询结果是latin1,可能隐式转换导致索引失效或匹配失败
REGEXP 和 LIKE 哪个更适合嵌套场景?
REGEXP 表达力强,但代价高——多数数据库没法对正则做索引优化,嵌套时性能雪崩风险更大;LIKE 虽简单,但配合固定前缀和索引更可控。
- 只匹配简单模式(如“以 A 开头、含 B、结尾是数字”)优先拆成多个
LIKE+AND,别一股脑塞REGEXP - MySQL 8.0+ 支持函数索引,可对
REGEXP_SUBSTR(col, '...')建索引,但维护成本高,嵌套里慎用 - PostgreSQL 的
~操作符底层调用的是 RE2,比老版本快,但依然不建议在子查询的WHERE里高频用
参数化查询里拼通配符,引号怎么处理才安全?
手拼 '%' + @param + '%' 是 SQL 注入温床;用参数占位符时,通配符必须由应用层加进去,不能丢给数据库拼。
- 正确做法:预编译语句中传入完整带通配符的值,例如 Python 的
cursor.execute("SELECT * FROM t WHERE name LIKE %s", ['%' + user_input + '%']) - 错误做法:写成
"name LIKE '%'+?+'%'"—— 不同驱动解析行为不一,SQL Server 可能报错,MySQL 可能绕过参数化 - ORM 如 SQLAlchemy,用
func.concat('%', col, '%')或ilike方法更稳妥,避免字符串拼接逻辑泄露到 SQL 层
实际跑起来才发现,嵌套 + 字符串匹配最麻烦的不是语法,是执行计划里那个没被用上的索引——它安静地躺在那儿,而你还在看 EXPLAIN 输出发呆。










