WordPress中的_Prime_POST_CACHES

时间:2016-11-03 作者:hguser

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;
}

2 个回复
最合适的回答,由SO网友:Rarst 整理而成

这些缓存位通常被认为是不可取的。如果我没记错的话,您可以通过查询参数和包装相关代码来控制行为wp_suspend_cache_addition() 呼叫。

从源代码来看,它似乎并不意味着要承载自定义逻辑。如果您希望非本机表中的自定义数据具有类似的行为,则可能需要自己为其实现缓存逻辑。

SO网友:Tom J Nowell

您的筛选不起作用,因为内容和标题的筛选发生在缓存之后,而不是之前。the_titlethe_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作业中提取数据(效率较低,需要权衡时间)。