WordPress 6.4 是如何改进对象缓存,提高站点的效率
WordPress 6.4 还增强改进了对象缓存的能力,这些功能改善了过滤器的处理,减少了数据库查询,并提高了整体系统效率。
get_option() 缓存改进
get_option()
函数为了优化考虑,如果查询到某个选项不存在,就会将该选项名记录到一个名为 notoptions
缓存中,这样就下次查询同样选项的时候,就直接从该缓存中得知不存在,从而避免了重复的数据库查询。
之前对 notoptions
的缓存查找是在检查请求的选项是否存在于缓存之前进行的,考虑到选项可能确实存在的可能性更大,因此在 6.4 版本做出了更改,调整了检查顺序,先验证选项在缓存中是否已存在,再确认其不存在,最后才到数据库中查询。这种调整不仅减少了冗余的查询,并且还消除了不必要的缓存查找,从而提高了整体的性能。
WP_Query
缓存改进
6.4 增强了 WP_Query 的查询性能,一共有三点:
强制分割查询
这是什么意思呢?WordPress 是在 3.1 版本时引入了分割查询的能力,即 WP_Query 中的主查询仅获取文章 ID 而不是整个文章对象,然后会基于这些文章的 ID 检测这些对应的文章的信息是否已经在内存缓存中,如果没有则调用函数 _prime_post_caches()
来获取完整的文章信息。
之前这个分割查询获取文章的能力限制在获取少于500篇文章的时候,现在在开启持久性/外部对象缓存时就会取消这个限制,因为 WordPress 已经引入 wp_cache_get_multiple()
方法,它支持在单次内存请求就能获取多个对象。
总结来说,执行分割查询和结合对象缓存,可以显著提升了 WordPress 的性能并减轻了数据库负担,可以让 WordPress 站点加载得更快,让用户获得更流畅的体验。
修正使用 filter 之后数据完整性问题
WP_Query
类允许开发者使用各种过滤器来自定义查询,比如 posts_fields_request
,posts_request
和 the_posts
等,这些过滤器在修改 WP_Query
的查询字段和修改获取到的文章对象的时候非常有用,但是这些修改也可能会导致获取的文章对象不完整或无效,为了确保数据的一致性和完整性,6.4 做了以下调整:
在使用了这些过滤器进行查询的场景中,WP_Query
的 get_posts()
方法不再使用 update_post_caches()
方法对文章进行缓存,而是使用 _prime_post_caches()
,这样的改进可以确保了数据的一致性和完整性,但也可能在填充文章数据缓存时候偶尔会触发新的数据库查询,所以在某些特定情况下它反而可能会略微增加数据库的负载。
改进 id=>parents 查询性能
在启用了对象缓存的网站,特别是后台有大量的页面需要处理的时候,当 WP_Query
的查询返回字段为 id=>parent
时可能存在一个性能问题。
为此 6.4 引入了一个新函数 _prime_post_parent_ids_caches()
,它可以为文章的父级准备专用的缓存,随后可以使用 wp_cache_get_multiple()
函数在一次请求中获取所有文章的父级数据,当然在调用 clean_post_caches()
函数时,文章父级的缓存也会被作废,如果你是直接在数据库更新文章,确保你的清理缓存的操作也要考虑到了这点。
WP_Term_Query 缓存改进
6.4 也增强了 WP_Term_Query 的查询性能,一共有两点:
增加了 cache_results 参数
通过引入 cache_results
参数让开发者对于 WP_Term_Query
查询的缓存行为有更好的控制,它允许开发者决定是否从查询缓存中加载结果,该参数是一个布尔值,当设置为 false 时,可以获得完全未缓存的结果。
$args = array(
'taxonomy' => 'category',
'cache_results' => false, // 这将获取未缓存的结果
);
$term_query = new WP_Term_Query($args);
cache_results
这个参数主要为一些需要高度自定义解决方案的开发者设计的,他们需要特定查询绕过缓存的机制。虽然在某些情况下它可能是有用的,但在禁用缓存时要小心,因为它可能会影响生产环境中的性能,
在大多数情况下,还是建议在生产环境中保持 cache_results
参数启用(设置为 true ),毕竟缓存是 WordPress 中的一个重要性能优化,禁用它可能会导致查询执行时间变慢,所以在决定禁用查询缓存之前,始终考虑项目的具体要求。
修正使用 filter 之后的缓存行为
同样在 WP_Term_Query
中使用 terms_clauses
或 get_terms_fields
过滤器时,并且修改了所选字段时,现在会缓存整个对象。这个改变是必要的,因为过滤器可以扩展所选字段,不仅仅是 term_id,其他相关的字段,如计数或父级,在查询时可能会被修改,缓存完整的对象确保这些修改过的字段在缓存中被正确的存储。