I was recently debugging the front page of a WordPress site and found a lot of queries to the terms and term relationships database tables.
Digging a little deeper, I found that the culprit were a set of functions that were calling wp_get_object_terms()
to get the terms from a set of looped posts… and then I thought… “wait a minute, doesn’t WordPress should be using the object cache for this?”
Well, it turns out that wp_get_object_terms()
always queries the database.
If you’re looping over WP_Query
results, you should prefer get_the_terms()
instead. It’s pretty much the same for most use cases, but it uses the object cache, which by default gets populated with the terms for the posts matching your query — unless you specifically set update_post_term_cache
as false when instantiating WP_Query
.
The are several differences, though: wp_get_object_terms()
can take arrays as the first and second argument, while get_the_terms()
can only take the post ID (or object) as first argument (so you can’t get the terms for a bunch of posts on one function call) and a string for taxonomy (so you can’t get the terms for several taxonomies); and you can use a third argument on the former, which the latter doesn’t have.
You could still emulate some of this, and still benefit from using the object cache; for instance, let’s see how you would get the names of the my_custom_tax
terms for the current post, ordered by use on a descending way.
// using wp_get_object_terms() $popular_terms = wp_get_object_terms( $post->ID, 'my_custom_tax', array( 'orderby' => 'count', 'order' => 'DESC', 'fields' => 'names' ) ); // using get_the_terms() $popular_terms = get_the_terms( $post->ID, 'my_custom_tax' ); // $popular_terms will be ordered alphabetically, so let's order by count $popular_terms = usort( $popular_terms, function( $a, $b ){ if ( $a->count < $b->count ) { return 1; } if ( $a->count > $b->count ) { return -1; } return 0; } ); // we only need slugs, so... $popular_terms = wp_list_pluck( $popular_terms, 'name' );
Even if it’s somewhat troublesome, it’s probably worth the effort if you’re trying to maximize for performance.