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 解析与优化成本显著上升,还可能撑爆语句长度限制;拼接用户输入时务必用参数化,避免注入与解析错误。