赞片CMSMySQL优化

chinaz
chinaz 正式会员超兽战士
发布于 2026-10-07 20:10 ·0 浏览 ·0 回复

照着做完,你能把赞片CMS 的 MySQL 从"每个页面都慢半拍"调到"打开列表页基本不查库"。

赞片CMS 是基于 ThinkPHP 3.2 的影视站程序,天生读多写少:一次列表页请求可能扫十几万行 zp_vod 表。所以优化思路不是"加机器",而是先定位慢查询 → 调 MySQL 参数 → 补索引 → 砍掉没用的查询。下面按顺序来。

第一步:开慢查询日志,先找出到底哪条 SQL 慢

这一步要拿到"实际执行超过 1 秒的 SQL 清单",不然所有调优都是瞎猜。

登录服务器后连上 MySQL:

mysql -uroot -p

在 MySQL 命令行里临时开启(重启失效,用来验证):

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
SET GLOBAL log_queries_not_using_indexes = ON;
SHOW VARIABLES LIKE 'slow_query_log_file';

永久生效改配置文件。宝塔面板用户走:软件商店 → MySQL 5.7 → 设置 → 配置修改,在 [mysqld] 段落下加:

slow_query_log = 1
slow_query_log_file = /www/server/data/mysql-slow.log
long_query_time = 1
log_queries_not_using_indexes = 1

保存后点同页面的「重启」,或命令行 systemctl restart mysqld。

跑半小时真实流量,然后看日志:

mysqldumpslow -s t -t 20 /www/server/data/mysql-slow.log

-s t 按总耗时排序,前 20 条就是你的重点。

注意:log_queries_not_using_indexes 在写入频繁的站点会撑爆日志文件,定位完就把它关掉(设为 0)。

第二步:按机器内存调 my.cnf 核心参数

这一步做完,InnoDB 的读操作大部分会命中内存,磁盘 IO 直接降一个量级。

还是软件商店 → MySQL → 设置 → 配置修改,按下表改(以 8G 内存服务器为例):

innodb_buffer_pool_size = 4G
innodb_buffer_pool_instances = 4
innodb_flush_log_at_trx_commit = 2
innodb_log_file_size = 256M
innodb_io_capacity = 2000
max_connections = 300
table_open_cache = 2000
tmp_table_size = 64M
max_heap_table_size = 64M
query_cache_type = 0
query_cache_size = 0

几个关键点:

  • innodb_buffer_pool_size 给物理内存的 50%~60%,这是最值钱的一个参数,别给超过 70%,要给 PHP 留内存。
  • innodb_flush_log_at_trx_commit = 2 把每次事务刷盘改成每秒刷一次,影视站丢一两秒数据无所谓,但写入速度能快好几倍。
  • MySQL 5.7 的 query_cache 在高并发下是全局锁,必须关;MySQL 8.0 已经移除该参数,不用管。

改完重启 MySQL。

注意:innodb_log_file_size 改大后如果启动失败,是旧的 ib_logfile 大小不匹配,删掉 /www/server/data/ib_logfile0 和 ib_logfile1 再启动(务必先备份数据库)。

第三步:给赞片CMS 的 vod 表补索引

这一步的目标是让列表页的"按分类 + 按时间排序"从全表扫描变成索引扫描。

先确认表前缀,默认是 zp_,不确定就在 phpMyAdmin 里点开数据库看一眼,或执行:

SHOW TABLES LIKE '%vod%';

用 EXPLAIN 看典型查询:

EXPLAIN SELECT * FROM zp_vod WHERE vod_type_id = 12 ORDER BY vod_time DESC LIMIT 20;

如果 type 列是 ALL,加联合索引:

ALTER TABLE zp_vod ADD INDEX idx_type_time (vod_type_id, vod_time);
ALTER TABLE zp_vod ADD INDEX idx_letter (vod_letter);
ALTER TABLE zp_vod ADD INDEX idx_name (vod_name(30));

再加索引后重新 EXPLAIN,type 应该变成 ref 或 range,rows 从六位数降到两位数。

注意:索引不是越多越好,每个索引都会拖慢写入。加完用 SHOW INDEX FROM zp_vod; 复查一遍,重复或从不被用到的索引(比如 vod_id 之外还单加 vod_type_id)直接 DROP INDEX 掉。

第四步:清掉垃圾数据并回收空间

这一步能立刻减小表体积,让上面的索引更容易常驻内存。

影视站的播放记录、搜索记录、采集临时表往往涨到几百万行却没人看。在宝塔 phpMyAdmin 里执行:

TRUNCATE TABLE zp_search_log;
TRUNCATE TABLE zp_play_log;

(表名以你站点实际为准,先用 SHOW TABLES; 列出来。)

删完大表后回收文件空间:

OPTIMIZE TABLE zp_vod;

也可以在宝塔 phpMyAdmin 里勾选表 → 底部「选中项」下拉 → 优化表。

注意:OPTIMIZE TABLE 会锁表,影视站晚高峰别做,放到凌晨 3 点后,或者写进宝塔的「计划任务 → 数据库备份」之后执行。

第五步:开启缓存,让大部分请求根本不碰数据库

这一步是收益最大的——前面都是让查询变快,这一步是让查询消失。

进赞片CMS 后台 → 系统 → 性能优化(部分版本叫「缓存设置」),打开:

  • 数据缓存:开启,缓存时间设 3600 秒
  • HTML 静态缓存:列表页和详情页都勾上

如果服务器装了 Redis,在宝塔 软件商店 → Redis → 设置 确认已启动,然后编辑赞片CMS 的数据库配置文件(ThinkPHP 3.2 一般在 Application/Common/Conf/config.php,找不到就执行):

grep -rn "DATA_CACHE_TYPE" /www/wwwroot/你的站点目录 --include="*.php"

把 DATA_CACHE_TYPE 改成 Redis,填上 Redis 的 127.0.0.1:6379。

改完清一次缓存:后台 → 系统 → 更新缓存。

注意:开了静态缓存后,新采集的影片不会立刻显示,需要手动「更新缓存」或等缓存过期。采集频繁的时段可以先临时关掉。

小结

  • 优化顺序固定:先开慢查询日志定位 → 再调 my.cnf → 再补索引 → 最后上缓存,跳步会白忙。
  • innodb_buffer_pool_size 设成物理内存的 50%~60%,是单点收益最高的参数。
  • MySQL 5.7 的 query_cache 必须关闭,8.0 直接用默认值。
  • 赞片CMS 的 zp_vod 表加 (vod_type_id, vod_time) 联合索引,列表页立刻见效。
  • 索引复查一遍,多余的删掉,否则拖慢采集写入。
  • OPTIMIZE TABLE 和清日志放到凌晨做,别在晚高峰锁表。
  • 最终目标是让缓存扛住 90% 的请求,MySQL 只处理剩下的 10%。
版权声明:本文来自 GJ站长论坛《赞片CMSMySQL优化》
原文链接:https://www.gj0.com/thread-515.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。

全部回复 0

还没有回复,来抢沙发~