首页/数据/数据库速查/IN 与 LIKE:集合匹配与模糊匹配
SQL 语法52 条

IN 与 LIKE:集合匹配与模糊匹配

IN 做集合匹配(命中索引仍可走 range);LIKE 前置通配符 % 会失效索引,全文检索需求应上 FULLTEXT 或外部搜索。

数据库速查数据更新于 2026-10-13

IN 与 LIKE 是什么

IN 做集合匹配:条件值个数不多时仍能利用索引做范围扫描;LIKE 做模糊匹配:只有前缀匹配(如 abc%)能用上索引,一旦通配符出现在开头就退化成全表扫描。需要真正的分词或全文检索时应该用 FULLTEXT 索引或外部检索引擎,而不是在业务表上堆各种 LIKE 变体。

基本信息

IN 语义等值集合匹配,元素数量不宜过大
LIKE 前缀abc% 可走索引范围扫描
LIKE 通配%abc% 与 %abc 无法使用索引
替代方案临时表加 JOIN、FULLTEXT 索引、外部搜索引擎
验证方式EXPLAIN 看 type、key 与 rows

典型使用场景

  • 按 ID 批量查询:IN 加索引即可,注意元素数量
  • 按单号前缀匹配:LIKE 'ORD2026%' 能走索引
  • 名称模糊搜索:应上 FULLTEXT 或外部检索引擎,而不是前置通配写法
  • 大集合查询:上千个 ID 改临时表 JOIN 或分批
  • 反向筛选:NOT IN 与 NOT LIKE 多数场景无法用索引
  • 多关键词搜索:交给外部检索组件处理分词与相关性

用法示例

用法示例
SELECT * FROM users WHERE id IN (1,2,3);
SELECT * FROM orders WHERE order_no LIKE 'ORD2026%';    -- 前缀匹配可用索引
SELECT * FROM products WHERE name LIKE '%phone%';       -- 前置通配,无法用索引
-- 大集合替代方案:上千个 id 时临时表加 JOIN 更稳
CREATE TEMPORARY TABLE tmp_ids (id BIGINT PRIMARY KEY);
INSERT INTO tmp_ids VALUES (1),(2),(3);
SELECT u.* FROM users u JOIN tmp_ids t USING(id);
EXPLAIN SELECT * FROM users WHERE id IN (1,2,3);   -- 确认 key 与 rows

索引可用性对照

写法能否用索引建议
id IN (1,2,3)可以,走范围扫描元素个数可控时优先使用
id IN (上千个值)理论上可以,解析与优化成本高改临时表 JOIN 或分批查询
LIKE 'abc%'可以,前缀范围扫描单号、编码等前缀查询首选
LIKE '%abc%'不可以,全表扫描改 FULLTEXT 或外部检索
NOT IN / NOT LIKE多数无法使用索引改写为反连接或先缩小范围
LIKE 前置通配与 NOT LIKE 都是全表扫描;正则、多关键词搜索建议上 FULLTEXT 索引或外部检索引擎。
IN 列表元素过多(常见经验是上千个)会让 SQL 解析与优化成本显著上升,还可能撑爆语句长度限制;拼接用户输入时务必用参数化,避免注入与解析错误。

易错点

  • 用 LIKE '%关键词%' 做搜索,数据量上来后每次都是全表扫描
  • 拼接 IN 列表时用字符串直接拼接,既有注入风险又容易超出语句长度
  • IN 列表塞入上千个值,解析耗时明显却以为索引已生效
  • NOT IN 遇到子查询返回 NULL 时结果为空,排查半天找不到原因
  • 在小表上看到全表扫描就优化,忽略数据量小本来就该走全表的情况

数据来源与参考

  • MySQL 8.0 Reference Manual: Pattern Matching

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌