问题描述

我正在阅读一些 best practices from 10up,他们提到在 WP_Query 中将这两个标志设置为 false(取决于您正在查询的内容):

  • 'update_post_meta_cache' => false:当后期元数据不被使用时很有用。

  • 'update_post_term_cache' => false:当分类术语不被使用时很有用。

我假设它使用像 update_post_caches()这样的东西,但我甚至不敢肯定这是什么意思。有人可以解释这两个标志在 WP_Query 中的含义,它们是多么有用吗?更多的信息越好,因为我不太了解 WordPress 如何缓存的东西,但是对于这两个标志的一个深思熟虑的答案也是可以接受的。

最佳解决方案

对象缓存无处不在

WordPress 尽可能地减少数据库查询的数量。

例如,任何时候您获得元字段或分类字段,在查询数据库之前,WordPress 会查看是否已经查询并存储在缓存中,并从中返回,而不是查询数据库。

“cache job” 是通过 WP_Object_Cache 类和 wp_cache_*函数完成的 (这是包装类的方法。)

缓存生活的地方

默认情况下,”cache” 只不过是一个 PHP 全局变量。这意味着它在内存中,也意味着它会在每个请求上消失。

但是,通过 dropins(advanced-cache.php 和/或 object-cache.php),可以设置一个自定义的方式来处理这个缓存。

通常,这个下拉菜单用于设置”survive” 单个请求的某种缓存机制。

由于这个原因,在 WP 的人中,这些都被称为”persistent cache” 插件 (即使在泡沫之外,”cache” 和”persistent” 也不会一起做出很大的意义) 。

现在的热门选择是 MemcachedRedis

因此,使用”persistent cache” 插件可以大大减少数据库查询的数量,因为缓存在每个请求上都不会更新。

一些例子

$foo = get_post_meta('foo', $post_id, true);
// a lot of code in the middle
$bar = get_post_meta('bar', $post_id, true);

上述 2 行代码将最多触发 1 个数据库查询。

实际上,当您查询自定义字段时,该数据库的所有字段都将从数据库中检索,通过对象缓存进行缓存,后续请求从缓存中提取数据,而不是从数据库中提取数据。

分类术语也是一样,WordPress 会将分类的所有术语拉一次,然后从缓存中返回。

对象缓存在 WordPress 中被广泛使用。不仅用于帖子,元值和分类,还可以为用户,评论,主题数据…

什么 WP_Query 与所有这一切有关系?

当您通过 WP_Query 查询某些帖子时,默认情况下,WordPress 不仅可以从数据库 (或从缓存中缓存) 中提取它们,还可以更新所有自定义字段的缓存以及与拉出的帖子相关的所有分类。

所以当你打电话时,例如 get_the_terms()get_post_meta(),而循环的帖子通过 WP_Query 得到,你实际上并不触发任何数据库查询,而是从缓存中提取信息。

好,不是吗

是的,但它带有成本。

缓存更新”magic”,WordPress 通过 WP_Query 拉动帖子发生在 update_meta_cache for meta 和 update_object_term_cache 用于分类。

如果您查看这些函数的源代码,您将看到 WordPress 在每个函数中只执行一个 db 查询,但也进行了大量的处理。例如,在 update_object_term_cache 中有 7 个嵌套的 foreach … 如果你有很多分类,每页的帖子数量很多,这不是很好。

关于 WP_Query 参数,最后

'update_post_meta_cache''update_post_term_cache'在设置为 false 时会做的是分别防止 WordPress 更新缓存的自定义字段和分类。

在这种情况下,第一次查询自定义字段或分类法时,将触发数据库查询,并缓存数据。

值得吗?

像往常一样,答案是否决定。大多数时间将这些值设置为 false 是一个不错的选择,因为它不需要时会阻止不必要的处理和数据库查询,并且无论如何,首次需要自定义字段/分类术语,缓存都会更新。

但是,如果您打算在 C 循环中调用 get_post_meta(),并且您将为帖子支持的所有 (或大多数) 分类而调用 get_the_terms(),那么缓存更新将被触发,并且可能没有实际的有利于将这些查询参数设置为 false

次佳解决方案

主要的兴趣点是 update_post_caches 功能。 WP_Query 从 DB 获取了所有的帖子后被调用。通常,您首先要发帖的原因是显示它们,通常意味着根据元数据显示术语和某些内容,因此,WP_Query 还将默认查询与返回的帖子相关的元数据和术语数据的 DB 并存储缓存*。这些信息在 WP_Query 返回的数据中不是明确提供的,但是当您调用相关 API 以获取特定帖子的术语和元信息时,它将已经在内存中可用,并且不需要发送新的查询到 DB 。

这使 Wordpress 能够通过仅发送一个请求来获取所有帖子的信息而不是向每个帖子发送请求来减少与向 DB 发送请求相关的开销。

现在我找不到什么时候不希望缓存更新的任何非常简单的例子,但是如果你只想要所有帖子的标题列表,可能是一个琐碎的例子。因此,您不需要术语或元数据。

* cache – 这里最重要的是基于内存的缓存,即使没有任何对象缓存插件的活动,WP 也可以存储其中的所有数据。显然,当您有对象缓存时,信息也将存储在那里。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。