WordPress 文章超过 10 万,负载过高?这是为什么?
这个问题是所有使用 WordPress 建站到一定规模后都会遇到的,一般人对此问题也都是泛泛而谈,常见的处理方式也都大同小异,并没有具体定位 WordPress 慢的方法,更没有针对问题提出解决方案。
我接过很多 WordPress 优化的单子,因此我将结合自己的经验,详细讲述我是如何处理这个问题的。
基础优化
首先,我将提供三点简单的优化建议:
将 WordPress 更新到 6.1,因为 WordPress 6.1 无需插件即可实现站点 0 SQL,这是最直接、最有效的操作。
WordPress 性能优化的基础是选择一款速度快的主题,很多 WordPress 站点速度很慢,其主要原因就是主题。
对 WordPress 进行基本的优化,WordPress 性能优化:为什么我的博客比你快,这篇文章中有非常详细的介绍,主要是两点:使用 CDN 对动静态资源进行分离和使用 Memcached 来缓存 WordPress 数据。
可能的原因
完成上述三点简单的基础优化操作后,如果速度仍然很慢,那该怎么办?根据我的经验,WordPress 速度太慢,通常可能是以下原因:
页面的 SQL 请求太多,导致数据库的请求池被耗尽。
HTTP 请求太多,且都没有做缓存,占用了过多的服务器资源。
主题或插件的 PHP 程序代码编写不当,甚至存在死循环,直接导致程序卡死。
Log 程序
如何定位这些问题呢?工欲善其事,必先利其器,因此我编写了一个 WordPress 各种 Log 记录的插件,专门用于定位这些问题:
如上图所示,该插件会每天孜孜不倦地记录程序的错误或警告,这样我就可以根据这些错误来优化和增强程序。很多时候,用户无法清晰地反馈自己的错误,而通过 Log 反而更容易定位代码问题,例如上面的 PHP log:
我截取其中一段,可以记录一个 PHP Warning 信息,以及 PHP 数组 Undefined index 的问题,具体发生在哪个文件、哪一行,具体的回调过程,请求的时间、地址、来源以及 Post 提交的数据都将被记录下来,这对解决问题有很大的帮助。
定位问题
你可能会问,这个 log 记录系统与 WordPress 慢有什么关系?
其实关系密切。通过 Log 是定位问题的最佳方法,为了解决程序慢的问题,我还专门对 超过 5 秒
才能打开的页面进行了详细记录。
我会记录该页面的调用时间、地址、传递的 POST 数据(如有)、来源以及具体耗时:
慢查询 Log 会记录该页面的所有 SQL 请求,包括共有多少条 SQL 请求、每条 SQL 具体是什么、耗时以及调用栈:
如果有 HTTP 请求,慢查询 Log 也会记录所有的 HTTP 请求,包括每条 HTTP 请求的链接、参数、耗时和调用栈:
解决问题
定位问题后,解决起来就非常方便了。
如果是 SQL 请求太多,是否在 for 循环中进行了 SQL 请求?如果是,就应该在 for 循环之前,通过获取所有 id 一次性获取数据,这样就不会一次耗尽数据库线程。
如果是 HTTP 请求太慢,是否可以将请求的结果缓存到 Memcached 中,这样下次就无需进行远程的 HTTP 请求,直接从内存中获取即可。
例如,一般来说相关文章是通过文章的标签的相关来生成的,这样就需要使用到文章和标签的关联表(wp_term_relationships)和文章表(wp_posts)进行连表查询,根据文章相关度进行排序。我见过一些文章数和标签数较多的站点,这样的一条 SQL 查询经常会耗时 5-10 秒,这样的慢查询很容易导致站点挂掉。
我是如何优化的呢?我放弃了连表查询,首先获取当前文章的标签,然后从文章和标签的关联表(wp_term_relationships)根据这些标签获取最相关的文章 ID,并多获取一些,比如要获取 5 篇,我就至少获取 10 篇,然后从文章表(wp_posts)中获取具体的数据,舍弃掉那些不符合文章类型和状态的,剩下的就符合要求了,如果数量不够,就继续上述方法再找一些,直至数量足够。这样通过 PHP 脚本进行优化,相关文章造成的性能问题就能得到完美解决。
