Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am not sure how WordPress cache the queries. I had the impression that whenever I execute a query through wpdb class, it gets cached. For example, on codex under Select a Row and Select a Var, it says the whole query is cached for later use. And I think which means if more data is requested in another query, partials or full results of which are already in wpdb cache, then those are used and a query doesn't happen(in case of full results already in cache). Am I correct in understanding?

I was trying something and I found that I can't use the cache. For reference, I was listing the recent comments the current user has made. I used get_comments() but since it only has post id in the results, I used get_the_title() inside the loop for displaying them. Obviously this is expensive in terms of query, so I though I can cache the required rows of post table by querying them beforehand so that get_the_title() does no actual query. I did something like

$query = implode( ' OR ID = ', $collect_post_ids );
$query = 'SELECT * FROM '.$wpdb->prefix.'posts WHERE ID = '.$query.';';
$wpdb->get_results( $query ); // just cache it

but that didn't help. get_the_title() is still doing queries. Most likely its me who has misunderstood how WP Cache works. So where I am wrong?

Here is the full code for reference - http://ashfame.pastebin.com/BpxjHiQr

share|improve this question
    
Maybe Scribu's comment here will shine some light(maybe not). core.trac.wordpress.org/ticket/16336 –  t31os Feb 2 '11 at 18:31
    
Not sure! Sorry couldn't make sense out of it. :/ –  Ashfame Feb 2 '11 at 18:36
    
As a side note: $wpdb->posts is the posts table so you don't have to prepend the prefix to a string. –  Zack Feb 2 '11 at 21:52
    
ah yes I forgot that we have table names saved too. Thanks :) –  Ashfame Feb 2 '11 at 22:26

3 Answers 3

up vote 3 down vote accepted

Nope, doesn't work like that. The database-related caching is minimal and mostly covers using precisely same queries during single page load.

Best way to cache persistently database and/or computationally intensive results is using Transients API to store results for fitting period of time.

share|improve this answer
    
Execute the same query twice and it still adds up one to the total query count. –  Ashfame Feb 2 '11 at 18:35
1  
@Ashfame I am not sure every query is cached, on the contrary it is probably far from it. Again - this might save some query here or there internally, but natively WP has no considerable cache for database queries to rely on. If you are especially concerned about queries there are plugins around that provide more extensive and reliable database caching. –  Rarst Feb 2 '11 at 18:39
    
Thanks! Plugins for providing caching or letting you debug? –  Ashfame Feb 2 '11 at 19:15
    
@Ashfame Caching. There are both multi-factor caching plugins and those that focus on database. Depends on your specific needs. –  Rarst Feb 2 '11 at 19:19
    
Sure! I would like to know more. I will digg in more sometime. –  Ashfame Feb 2 '11 at 20:10

The docs suggested to me that the output from a query was only cached for that specific request - so presumably Wordpress is doing a buffered query on MySQL.

In my case, I used the wp_cache_* functions - see http://codex.wordpress.org/Class_Reference/WP_Object_Cache

Example code:

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>";
}
share|improve this answer

The solution @GingerDog gave works perfectly, but only does so within a single page refresh. If you want to cache your query result for a session you can use a similar solution with $_SESSION (whereas the Transients API works across sessions and machines).

$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;
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.