电脑指南
第二套高阶模板 · 更大气的阅读体验

数据库慢得像卡住?几个小设置就能避开全表扫描

发布时间:2026-04-23 16:31:08 阅读:3 次

你有没有遇到过:后台跑个查询,页面转圈十几秒没反应,服务器风扇呼呼响,日志里还飘着一行“Query took 12.8s”?十有八九,数据正在吭哧吭哧地翻遍整张表——也就是常说的“全表扫描”。它不挑食,不管你要找的是第1条还是第100万条,统统从头扫到尾。

为啥全表扫描这么伤?

想象一下,你家书架堆了5000本书,朋友让你找一本叫《Linux命令速查》的书。如果你没贴标签、没分类、连索引页都没有,只能一本本抽出来翻封面——这就是全表扫描。数据量小还好,一旦表涨到百万行,每次查询都在硬盘上狂奔,CPU和IO直接拉满。

最管用的三招,立马见效

第一,给常用查询字段加索引。比如用户登录总按 username 查,订单列表老按 statuscreated_at 筛,这些字段就是索引的首选目标。别一上来就给所有字段建索引——索引本身也占空间、拖慢写入速度。先看慢查询日志,揪出高频 WHERE 条件里的字段。

MySQL 里加索引很简单:

ALTER TABLE users ADD INDEX idx_username (username);

第二,别让索引“失效”。写了索引却没用上,很常见。比如在 WHERE 里对索引字段用了函数:WHERE YEAR(created_at) = 2024,或者加了前导通配符:WHERE name LIKE '%小明'。这种写法会让索引直接歇菜。改成 WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01',或 WHERE name LIKE '小明%',索引就能重新上岗。

第三,限制返回结果数量。管理后台的列表页,用户一次最多看30条。但有些代码写着 SELECT * FROM orders,再在 PHP 里 array_slice。数据库可不管你要不要,照单全取。加上 LIMIT 30,它只捞前30行,省力又省心:

SELECT id, title, status FROM articles ORDER BY created_at DESC LIMIT 30;

顺手检查的小动作

执行完查询,加个 EXPLAIN 前缀看看执行计划:

EXPLAIN SELECT * FROM logs WHERE level = 'error' AND time > '2024-06-01';

重点盯 type 这一列:如果是 ALL,说明正在全表扫描;要是看到 refrange,基本就稳了。再看 rows 数字,如果动辄几十万,那这句 SQL 就该优化了。

系统设置不是调个分辨率、换张壁纸那么简单。数据库怎么查、索引怎么建、SQL 怎么写,这些藏在后台的配置,才是让网站真正“丝滑”的关键。