通过wpdb类执行的查询会被缓存吗?

时间:2011-02-02 作者:Ashfame

我不确定WordPress如何缓存查询。我的印象是,每当我通过wpdb类执行查询时,它都会被缓存。例如,在codex上的Select a Row and Select a Var下,它表示整个查询将被缓存以供以后使用。我认为这意味着,如果在另一个查询中请求更多数据,部分或完整结果已经在wpdb缓存中,那么这些数据就会被使用,并且查询不会发生(如果完整结果已经在缓存中)。我的理解正确吗?

我尝试了一些东西,发现我无法使用缓存。为了便于参考,我列出了当前用户最近发表的评论。我曾经get_comments() 但由于结果中只有post-id,我使用get_the_title() 在循环中显示它们。显然,这在查询方面很昂贵,所以我想我可以通过预先查询post表中所需的行来缓存它们,以便get_the_title() 不执行实际查询。我做了一些

$query = implode( \' OR ID = \', $collect_post_ids );
$query = \'SELECT * FROM \'.$wpdb->prefix.\'posts WHERE ID = \'.$query.\';\';
$wpdb->get_results( $query ); // just cache it
但这没有帮助。get_the_title() 仍在进行查询。很可能是我误解了WP缓存的工作原理。那么我错在哪里呢?

以下是完整代码供参考-http://ashfame.pastebin.com/BpxjHiQr

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

不,不是那样的。与数据库相关的缓存非常少,主要包括在单页加载期间使用完全相同的查询。

持久缓存数据库和/或计算密集型结果的最佳方法是使用Transients API 存储拟合时间段的结果。

SO网友:David Goodwin

这些文档表明,查询的输出仅针对该特定请求进行缓存,因此WordPress可能正在MySQL上进行缓冲查询。

在我的例子中,我使用了wp\\u cache\\u*函数-请参阅http://codex.wordpress.org/Class_Reference/WP_Object_Cache

示例代码:

sql = "
    SELECT {$wpdb->posts}.* FROM {$wpdb->posts}
    LEFT JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)
    LEFT JOIN {$wpdb->term_taxonomy} ON ({$wpdb->term_relationships}.term_taxonomy_id = {$wpdb->term_taxonomy}.term_taxonomy_id)
    WHERE ({$wpdb->term_taxonomy}.taxonomy = \'category\' AND {$wpdb->term_taxonomy}.term_id = 9849 )
    AND
    {$wpdb->posts}.post_status = \'publish\' AND
    {$wpdb->posts}.post_type = \'post\' ORDER BY {$wpdb->posts}.post_title ASC";

$posts = wp_cache_get(md5($sql), \'somerandomkey\');
if($posts === false) {
    $posts = $wpdb->get_results($sql, OBJECT);
    wp_cache_add(md5($sql), $posts, \'somerandomkey\');
}

if(empty($posts)) {
    echo "<p>No results found </p>";
}

SO网友:Sjeiti

@GingerDog提供的解决方案非常有效,但只能在一个页面刷新内完成。如果要缓存会话的查询结果,可以对$\\u会话使用类似的解决方案(而Transients API可以跨会话和机器工作)。

$sQuery = "SELECT `ID`,`post_name` FROM `wp_posts` WHERE `post_type` = \'attachment\' AND `post_name` LIKE \'foobar%\'";
$sQueryMD5 = md5($sQuery);
if (isset($_SESSION[$sQueryMD5])){
    $aResult = $_SESSION[$sQueryMD5];
} else { // search wp_posts
    $aResult = $wpdb->get_results($sQuery, OBJECT);
    $_SESSION[$sQueryMD5] = $aResult;
}

SO网友:rebe100x

下面是一个使用transients 它依赖于您的数据库。

$query = \'SELECT * FROM \'.$wpdb->prefix.\'posts WHERE ID = 1;\';

// Check for transient. If none, then execute WP_Query
if ( false === ( $posts = get_transient( \'cached_posts\' ) ) ) {
    $posts = $wpdb->get_results( $query );

    // Put the results in a transient. Expire after 1 minute.
    set_transient( \'cached_posts\', $posts, 60 );
    echo \'request executed and cached for 1 min\';
}
var_dump($posts);

结束

相关推荐

$wpdb->日期时间列的INSERT()和值?

我有一个带有DATETIME列的自定义表。我有一个添加记录的功能;我想添加一个$expires 此函数的参数,该参数可以保存unix时间戳,指出记录应在何时过期。我想使用$wpdb->insert() 填充此列。到目前为止,我还找不到WordPress的便捷功能来将时间戳转换为“YYYY-MM-DD HH:MM:SS”格式。有这样一个内置的吗,还是我应该使用$wpdb->prepare(), 或者可能是第三种选择?