news 2026/7/14 8:50:44

一个模糊查询让我的接口超时了

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一个模糊查询让我的接口超时了

前两天给博客加了个文章搜索功能,用户输入关键词,后端查 MySQL。

写完上线,一切正常。

五分钟后用户群炸了——搜索接口超时,等了 4 秒才返回。


第一反应:数据不多啊

博客总共几百篇文章,title字段加了索引。按理说应该秒出。

打开 SQL 日志一看:

SELECT*FROMarticlesWHEREtitleLIKE'%微服务%'ANDdeleted=0

LIKE '%xxx%'——左模糊。一瞬间反应过来了。

MySQL 的 B+Tree 索引是按字符串从左到右排序的。左边是通配符,引擎不知道从哪开始找,索引直接报废。

EXPLAIN验证:

+----+------+---------------+------+---------+------+------+------------+ | id | type | possible_keys | key | key_len | ref | rows | Extra | +----+------+---------------+------+---------+------+------+------------+ | 1 | ALL | idx_title | NULL | NULL | NULL | 387 | Using where| +----+------+---------------+------+---------+------+------+------------+

type=ALL,全表扫描。387 行不多,但每行都要走一遍LIKE匹配,不超时才怪。

LIKE 模糊查询的索引规则

只有一种写法能走索引:

-- ✅ 走索引WHEREtitleLIKE'微服务%'-- ❌ 不走索引WHEREtitleLIKE'%微服务'WHEREtitleLIKE'%微服务%'

前缀匹配没问题,因为 B+Tree 能定位到「微」字开头的所有记录。但一旦左边有%,引擎就不知道从索引树的哪个节点开始找了。

不只是 LIKE:五种最常见的索引失效场景

排查过程不是孤立事件。顺手整理了五个日常开发里最容易踩的坑。

1. 对索引列做函数操作

-- ❌ 不走索引WHEREDATE(create_time)='2026-07-13'-- ✅ 走索引WHEREcreate_time>='2026-07-13 00:00:00'ANDcreate_time<'2026-07-14 00:00:00'

索引存的是原始值,套了DATE()函数它就认不出来了。范围查询是正解。

2. 隐式类型转换

-- phone 是 VARCHAR 类型,加了索引-- ❌ 不走索引WHEREphone=13558035960-- ✅ 走索引WHEREphone='13558035960'

MySQL 做类型转换时会把字符串转数字去比较,等于给索引列套了一层隐式函数。EXPLAIN里会看到Using index condition但实际typeindex不是ref

3. OR 条件

-- ❌ 部分不走索引WHEREtitle='微服务'ORcontentLIKE'%部署%'-- ✅ 用 UNION 改写SELECT*FROMarticlesWHEREtitle='微服务'UNIONSELECT*FROMarticlesWHEREcontentLIKE'%部署%'

OR 两边只要有一边索引失效,整个查询走全表。拆成 UNION,各自走各自的索引。

4. NOT、!=、<> 负向查询

-- ❌ 不走索引WHEREstatus!=1WHEREstatusNOTIN(1,2,3)-- ✅ 走索引WHEREstatus=0WHEREstatusIN(0,4,5)

优化器认为负向查询会扫大部分数据,不如全表快。能正向写就正向写。

5. 联合索引不满足最左前缀

-- 联合索引:(a, b, c)-- ✅ 走索引WHEREa=1WHEREa=1ANDb=2WHEREa=1ANDb=2ANDc=3-- ❌ 不走索引(跳过了 a)WHEREb=2WHEREb=2ANDc=3-- ⚠️ 只走 a 的索引,b 不走WHEREa=1ANDc=3

联合索引像字典——先按 a 排序,a 相同再按 b 排序。跳过 a 直接查 b,索引树用不上。

回到我的搜索功能:三种解法

方案一:全文索引(推荐)

MySQL 5.7+ 内置中文分词(ngram),建全文索引后MATCH ... AGAINST走全文检索,LIKE '%xxx%'的问题绕过去了。

ALTERTABLEarticlesADDFULLTEXTINDEXft_title(title)WITHPARSER ngram;SELECT*FROMarticlesWHEREMATCH(title)AGAINST('微服务'INBOOLEANMODE)ANDdeleted=0;

几百篇文章,查询从 4 秒降到 0.05 秒。

方案二:Elasticsearch

文章量大了全文索引扛不住再上 ES。现阶段没必要,一台 2C4G 的 ECS 跑不动 ES。

方案三:前端防抖 + 缓存

搜索框输入防抖 300ms,热门关键词缓存到 Redis。没打到索引层的问题,但能降负载。这次没用上,先记着。

我选了方案一——改动最小,效果立竿见影。


五个索引失效场景,本质上是一个问题:索引是按规则排好的,你打破了规则,它就罢工。

写完代码跑一遍EXPLAIN,花十秒钟,省掉半夜爬起来改 SQL 的噩梦。


关于作者:无羡,独立开发者,全栈工程师,专注 AI 应用与微服务架构。

📌 分类:独立开发实战

🔗 个人博客 — 更多技术文章
✨ 开发者福利整理 — 云服务资源汇总
📂 软件工坊 — 我的技术分享
🌐 个人门户 — 独立开发作品全集

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 8:50:23

LV3296与MK22FN512VLH12在嵌入式数据采集系统中的应用

1. 项目概述&#xff1a;LV3296与MK22FN512VLH12的协同工作场景 在嵌入式系统开发中&#xff0c;数据采集与处理的实时性要求越来越高。LV3296作为一款高性能信号调理芯片&#xff0c;与NXP的MK22FN512VLH12微控制器组合&#xff0c;能够构建出稳定可靠的信息捕获系统。这套方案…

作者头像 李华
网站建设 2026/7/14 8:50:06

VibeThinker-3B-4bit高级应用:代码生成与逻辑推理实战案例

VibeThinker-3B-4bit高级应用&#xff1a;代码生成与逻辑推理实战案例 【免费下载链接】VibeThinker-3B-4bit 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/VibeThinker-3B-4bit 想要掌握AI代码生成和逻辑推理的核心技术吗&#xff1f;VibeThinker-3B-4…

作者头像 李华
网站建设 2026/7/14 8:49:43

Pandas多维聚合实战:业务分析的高效数据处理方法论

1. 项目概述&#xff1a;为什么“多维聚合”不是Pandas进阶技巧&#xff0c;而是业务分析的生存技能我在银行风控部门干了七年&#xff0c;从刚毕业写SQL查数的分析师&#xff0c;到带三个人小团队做反欺诈模型的数据架构师。这七年里&#xff0c;我亲手重构过四套核心报表系统…

作者头像 李华
网站建设 2026/7/14 8:48:17

Go语言手写神经网络:生产级前向传播与反向传播实现

1. 项目概述&#xff1a;为什么在 Go 里手写神经网络不是“炫技”&#xff0c;而是真需求 “How To Build Your Own Neural Network in the Go Programming Language”——这个标题乍看像极了程序员的自我挑战&#xff1a;用一门以简洁、并发和部署效率见长的系统级语言&#x…

作者头像 李华
网站建设 2026/7/14 8:48:10

职场AI化:三层能力体系与转型实战指南

1. 职场AI化浪潮下的生存法则 当ChatGPT在2022年底横空出世时&#xff0c;大多数职场人还把它当作新奇玩具。但短短18个月后&#xff0c;全球已有37%的企业将AI工具纳入日常工作流程。我最近为某跨国零售集团做数字化转型咨询时&#xff0c;亲眼目睹了市场部用AI工具替代了60%的…

作者头像 李华