wordpress似乎会缓存所有数据,包括当前页面中所有帖子的元数据_prime_post_caches
:
如图所示,它试图获取(76-100)内帖子id的信息。
在我的项目中,帖子的大部分数据都保存在另一个表中,而不是wp_posts
表或wp_posts_meta
我的自定义插件的表。因此,上面的查询将只缓存帖子的基本信息。
因此wordpress将尝试为页面中的每个帖子触发sql查询:
甚至我都用过wp_cache_add()
为了确保某个帖子的这种查询只会被查询一次,我认为如果我可以通过一个sql查询将它们全部选中,可能会更好。
然而,通过_prime_post_caches, 这个方法是私有的,我没有找到任何可以用来缓存它们的操作。
有什么想法吗?
Update1 :
我之所以使用单独的表来保存数据,是因为这些数据是由我无法控制的另一个系统生成的。虽然该系统没有视图模型,所以我在这里使用WordPress。
我使用$wpdb
与数据库通信。实际上,有两个表由一个键连接,以获取单个记录的完整信息。
Update 2:
下面是我如何使用挂钩获取自己的数据:
add_filter("the_title", function ($origin_content, $id) {
$info = my_get_info($id);
return $info["name"];
}, 10, 2);
add_filter("the_content", function ($origin_content) {
$info = my_get_info(get_the_ID());
return $info["summary"];
});
function movie4oy_get_info($post_id)
{
$guid = get_the_guid($post_id);
$result = wp_cache_get($guid, "_my_post_info");
if (!$result) {
$data = _my_get_info_db($guid);
if ($data) {
wp_cache_add($guid, $data, "_my_post_info");
$result = $data;
}
}
return $result;
}
function _my_get_info_db($guid)
{
global $SQL;
global $wpdb;
$row = $wpdb->get_row($wpdb->prepare($SQL,$guid), ARRAY_A);
$data = array(
......
);
return $data;
}
SO网友:Tom J Nowell
您的筛选不起作用,因为内容和标题的筛选发生在缓存之后,而不是之前。the_title
和the_content
显示该数据时使用。如果它们按照您的预期工作,就不可能在同一页面上以不同的方式过滤内容。
e、 g.以下是事情的顺序:
WP\\u查询类发出请求请求由数据库处理结果存储在每个post模板调用的WP\\u缓存中the_title
<修改此模板中标题输出的最后一次机会发生在the_title
筛选模板调用the_content
<修改此模板中输出内容的最后机会发生在the_content
过滤器是嵌入的,会出现短代码。至此,缓存已经发生。这些过滤器不是在缓存内容之前更改内容的机会,而是修改最终内容的机会。
要使过滤器正常工作,您需要在WP_Query
阶段这就是为什么您的代码能够正常工作并给出正确的结果,但性能不佳。
最重要的是,没有持久对象缓存,WP_Cache
对你没什么帮助。第二次请求相同的数据将避免第二次查询,但一旦页面完成加载,所有数据都会消失。下一次页面加载将需要再次获取它。由Redis/Memcached/etc支持的对象缓存可以解决这个问题。
相反,您需要采取一种非常不同的方法,通过复制数据。
将标题存储在posts标题中,将内容存储在posts内容中,这样它们就可以像标准的普通post一样工作,而不需要过滤器或特殊的mysql调用。这立即为您节省了2个昂贵的SQL调用,无需在WordPress中编写任何SQL查询,并让您充分利用WordPress所能做的所有缓存。
在您的另一个系统中,当内容发生更改时,ping WordPress安装以指示某个特定内容已过时,并随附发送新数据。REST API端点应该可以很好地实现这一点。
添加一些代码以确保标题和内容不能从WordPress更改,并且您已排序。现在你有了正常的标准帖子,就像其他WordPress网站上一样。
如果无法推送,请考虑从常规cron作业中提取数据(效率较低,需要权衡时间)。