应使用全文索引+缓存+防抖+游标分页优化搜索:建 fulltext 索引,用 match...against 查询;apcu/redis 缓存结果;前端防抖+后端限流;分页改用 cursor 替代 offset。

用 MySQL 全文索引替代 LIKE %keyword% 查询
直接 SELECT * FROM posts WHERE title LIKE '%php%' 在数据量超过几千行后就会明显变慢,因为无法走普通 B-Tree 索引。MySQL 的 MATCH ... AGAINST 全文索引能大幅加速关键词匹配,且天然支持自然语言模式下的词干、停用词过滤。
实操建议:
- 确保字段类型是
TEXT或VARCHAR(长度 ≤ 1000),并添加全文索引:ALTER TABLE posts ADD FULLTEXT(title, content) - 查询时用
MATCH(title, content) AGAINST('php' IN NATURAL LANGUAGE MODE),不要用布尔模式除非你明确需要+/-语法 - 注意:MyISAM 和 InnoDB 都支持,但 InnoDB 要求 MySQL ≥ 5.6,且默认最小词长为 4(
ft_min_word_len),搜 “php” 会失败——需改配置并重建索引
加缓存层避免重复查库
用户连续输入“php”,触发“ph”“php”“php ”三次请求,后两次其实可以复用前一次结果,尤其当搜索逻辑含 JOIN 或聚合时,数据库压力陡增。
实操建议:
- 用
apcu_fetch()做进程内缓存(PHP-FPM 模式下最轻量):$key = 'search_' . md5($keyword . $page); $result = apcu_fetch($key); - 缓存时间设短些(比如 60 秒),避免 stale 数据;命中率低时别硬缓存,先用
apcu_sma_info()看内存碎片 - 如果部署多台 PHP 服务器,换
redis,用$redis->get("search:{$hash}"),记得设 TTL
前端防抖 + 后端限流
用户在搜索框狂敲键盘,前端没防抖,后端每按一个键就收一个请求,瞬间堆积几十个并发查询,数据库连接池打满,其他接口也跟着卡。
实操建议:
- 前端 JS 必须加防抖:用
setTimeout延迟 300ms 才发请求,输入停顿后再查 - 后端加简单限流:记录 IP + 关键词哈希的 1 分钟请求数,超 5 次就返回
HTTP 429,用$_SERVER['REMOTE_ADDR']+md5($q)当 key 存 APCu - 别依赖前端传来的
limit参数,后端强制写死LIMIT 20,防止恶意传limit=100000拖垮查询
分页用游标(cursor)代替 offset
用户翻到第 100 页,OFFSET 2000 会让 MySQL 扫描前 2000 行再扔掉,越往后越慢。游标分页靠上一页最后一条记录的唯一字段(如 id)做条件,每次只查 20 条。
实操建议:
- 首次请求不带 cursor,返回数据时附带
"next_cursor": "12345"(即最后一条记录的id) - 下一页查:
WHERE id - 必须给排序字段加索引,比如
INDEX idx_id_ft (id),否则WHERE id 仍可能全表扫
真正卡顿往往不是算法问题,而是没意识到 LIKE 是全表扫描、没压住并发、或者分页用 OFFSET 走到第 50 页就开始抖。这几个点调完,万级数据下搜索响应基本能稳在 100ms 内。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











