优化 AutoLoad
MySQL 表的 autoload 属性控制表是否在数据库启动时自动加载到内存中。
- 设置为 1 时,表会在数据库启动时自动加载,可提高频繁查询的表的速度,但也占用内存空间。
- 设置为 0 时,表不会自动加载,可节省内存空间,但首次查询时需要加载,速度较慢。
对于较为大型的 WordPress 站点,请一定要看看“wp-postmeta”表的大小以及行数,一般情况下这个表可能是你数据库中最大的表,可以用以下命令查询哪个是你数据库中最大的表,以及这个表有多少 MiB 有多少行数据
SELECT table_name,
(data_length + index_length) / 1024 / 1024 AS total_mib,
table_rows
FROM information_schema.tables
WHERE table_schema = 'wordpress'
ORDER BY (data_length + index_length) DESC
LIMIT 1;
它的输出可能类似于这样,table_name 指最大表的表名,total_mib 指最大表的大小(MiB),total_rows 指最大表中有多少行数据
| table_name | total_mib | total_rows |
| ----------- | --------- | ---------- |
| large_table | 10.24 | 100000000 |
如果比较大的这些表是你常用的表,可以将其设置为 autoload,这样会牺牲部分内存空间来换取更快的查询速度,内存占用空间取决于你设置 autoload 表的大小,一般情况下会在表大小的基础上多占用 10%-50%
我们使用一种简单的方式(复杂的方式我不会)来设置一下 WordPress 设置项的 autoload,首先你可以安装一个插件(及其推荐),名为“Database Cleaner”,这个插件可以让你在 WordPress 中直接清理数据库而无需了解复杂的 SQL 查询命令
如你所见,可以直接设置 Options 中的东西是否自动加载,如果你希望取消自动加载,可以去掉最右侧的勾
如果你不知道这个设置项是干什么的,可以参考 Used By 以及点击 Size 一列的查询图标来查看这个设置项里究竟存了什么东西
对于已经禁用或删除的插件,在 Used By 一列中也会有对应的提示
减少废表数量
还是这个插件,点击 Tables 栏目可以看到哪些表是哪些插件使用的,删除表时建议仔细研究这个表是由哪个插件创建的,否则如果误删会出现稀奇古怪的问题
你可以通过这里的按钮来切换优化表/删表模式
清理文章修订
在 WordPress Core 栏目中可以看到显示出了文章修订的数量、自动草稿以及回收站中的文章的数量,如果没有版本修订的需求可以放心删除,当然,你也可以限制每篇文章的最大修订数量,超过这个数量后会在生成新的修订时删除最旧的一个
// 最大修订数量
define( 'WP_POST_REVISIONS', 3 );
整理碎片
在数据库中运行这条查询来整理碎片,此时 MySQL 会重建表,执行完成后可以看到查询花费了 29.1617 秒
参考:
MySQL :: MySQL 8.0 Reference Manual :: 17.11.4 Defragmenting a Table
正确选择数据库版本
众所周知,MySQL 目前被主要使用的版本是 5.7 和 8.x,可以参考网上的性能测试来选择数据库,此外,如果你是大型网站在使用 WordPress 可以尝试使用 MariaDB,因为 MariaDB 在大型数据库的查询中有着略微优势
对于有索引的情况下查询大量数据,MariaDB 的查询速度确实比 MySQL 要快
项目\数据库 | MySQL | MariaDB |
---|---|---|
查询time字段最值 | 0.006秒 | 0.001秒 |
过滤time字段并排序 | 0.398秒 | 0.020秒 |
查询level字段 | 0.065秒 | 0.049秒 |
查询message字段 | 0.003秒 | 0.005秒 |
MySQL 读写分离
在大多数情况下,MySQL 读写分离可以带来不小的性能提升,建议使用一主多从的形式,主库写入,从库读取,并且从库处于只读模式下性能会有较大的提升
你可以使用一些中间件来实现无需修改应用源码即可实现读写分离,如果你使用 WordPress 并且懒得去部署一个中间件,可以尝试目前已有的开源插件 LudicrousDB (github.com) 来实现读写分离,但这种方式通常只会在某些特定的 PHP 版本上正常工作,因此需要做好测试,并且在开发环境测试稳定后再逐步部署进生产环境
为此,我们需要使用多个服务器来组成 MySQL 读写分离或者分库分表的集群,使用 Docker 在同一服务器内部署多个 MySQL 实例所带来的提升不一定会很大,最好的办法是使用多台云服务器组成集群,我们可以选择支持内网互联的云服务商,避免流量走公网造成一定的延迟
目前,雨云的部分节点已经支持多服务器内网互通,这非常适合做 MySQL 数据库集群,如果你想,也可以顺便做一个 Redis 集群,如果你想尝试,请至少购买3台服务器搭建,或者购买一台配置略高的服务器,使用 Docker 开多个实例进行练习
暂无评论内容