MySQL索引优化,CMS文章查询提速
CMS文章越来越多以后,后台列表和前台栏目页打开变慢,通常不是服务器配置不够,而是文章查询没有走好索引。
MySQL索引优化要解决的核心问题,就是让数据库用更少的扫描行数找到目标数据。
下面按定位、优化、验证的顺序讲清楚,零基础也能跟着做。
先找到拖慢文章查询的SQL
优化不能凭感觉,先确认哪条SQL慢。
MySQL自带慢查询日志,开启后会把执行时间超过阈值的语句记录下来。
登录MySQL后执行:
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
如果 slow_query_log 是 OFF,
可以在配置文件 my.cnf(宝塔面板路径一般为 /etc/my.cnf 或 /www/server/mysql/etc/my.cnf)的 [mysqld] 段加入:
slow_query_log = 1
slow_query_log_file = /var/log/mysql-slow.log
long_query_time = 1
改完重启MySQL:systemctl restart mysqld。
之后观察 /var/log/mysql-slow.log,重点关注CMS文章列表相关的 SELECT 语句。
用EXPLAIN判断索引有没有生效
拿到慢SQL后,在语句前面加 EXPLAIN 再执行一次,例如:
EXPLAIN SELECT id,title FROM cms_article WHERE category_id=5 AND status=1 ORDER BY create_time DESC LIMIT 20;
重点看几个字段:
type:出现ALL表示全表扫描,是最差的情况;ref、range、index相对较好。key:显示实际使用的索引,如果是NULL,说明没走索引。rows:预估扫描行数,数值越接近实际返回条数越好。Extra:出现Using filesort或Using temporary,说明排序或分组没有借助索引。
只要 type 是 ALL 或 key 为 NULL,基本可以确定这条文章查询需要加索引。
给CMS文章表建立合适的索引
索引不是越多越好,要按查询条件组合来建。
常见的CMS文章列表查询条件包括栏目ID、状态、发布时间、是否置顶等。
以文章表 cms_article 为例,如果列表SQL经常按栏目筛选、按状态过滤、再按时间倒序,可以建立联合索引:
ALTER TABLE cms_article ADD INDEX idx_cat_status_time (category_id, status, create_time);
字段顺序很关键,一般把区分度高、经常做等值查询的字段放前面,范围查询和排序字段放后面。
如果文章详情按ID或别名查询,主键本身已有索引,别名字段可单独加索引:
ALTER TABLE cms_article ADD INDEX idx_slug (slug);
宝塔面板用户也可以在“数据库”页面找到对应表,点击“管理”进入phpMyAdmin,在“结构”里添加索引,效果与命令行一致。
哪些做法容易让索引白建
索引建了却没提速,多数是下面几种情况造成的:
- 在索引列上使用函数或运算,比如
WHERE DATE(create_time)='2025-01-01',会导致索引失效,应改成范围条件。 - 使用
LIKE '%关键词%'前置百分号,无法走普通索引,文章搜索可考虑全文索引或搜索服务。 - 联合索引字段顺序与实际查询条件不匹配,比如查询条件没有用到最左字段。
- 表数据量很小,MySQL可能直接全表扫描,加索引反而增加写入负担。
- 索引过多会拖慢文章发布和更新速度,建议控制在满足主要查询即可。
优化后如何确认真的变快了
索引调整完,重新执行一次 EXPLAIN,确认 type 不再是 ALL、key 显示了新建的索引、rows 明显下降。
再对比优化前后页面打开速度,可以用:
SHOW PROFILES;
或直接在CMS前台刷新文章列表,观察响应时间。
如果 Extra 里不再出现 Using filesort,说明排序也用上了索引,提速会更明显。
需要提醒的是,索引优化要结合真实数据量和查询频率来判断,建议在测试环境验证后再操作生产库,并提前备份文章表数据。
常见疑问
加了索引为什么查询还是慢?
先看 EXPLAIN 的 key 是否真的用上了新索引,再检查SQL条件是否对索引列做了函数处理,或者联合索引顺序不对。
CMS文章表索引越多越好吗?
不是。
索引会占用空间并影响写入速度,文章频繁发布时更明显,按主要查询建2到3个联合索引通常够用。
不重启MySQL能加索引吗?
可以,ALTER TABLE 在线加索引一般不需要重启,但大表操作可能锁表,建议低峰期执行并先备份。
优化后需要改CMS代码吗?
多数情况不用,索引生效后原SQL就会变快;
如果SQL写法本身有问题,比如用 SELECT * 或函数条件,配合调整查询语句效果更好。