Object cache everywhere
WordPress tries to reduce the number of database queries as much as possible.
For example, anytime you get a meta field or a taxonomy field, before querying the database, WordPress looks if that that was already queried and stored in cache, and returns it from there instead of querying the database.
The "cache job" is done via
WP_Object_Cache class and
wp_cache_* functions (that are wrapper to that class methods.)
Where cache lives
By default, the "cache" is nothing more than a PHP global variable. It means that it is in memory, but also means that it vanishes on every request.
However, via dropins (
advanced-cache.php and / or
object-cache.php), it is possible to setup a custom way to handle this cache.
Usually, this dropins are used to setup some sort of caching mechanism that "survive" the singular requests.
For this reason, among WP people, these are know as "persistent cache" plugins (even if outside the bubble the words "cache" and "persistent" don't not make a lot of sense together).
Popular choices nowadays are Memcached or Redis.
So using "persistent cache" plugins you can drastically reduce the number of database queries, because the cache is not updated on every request.
$foo = get_post_meta('foo', $post_id, true);
// a lot of code in the middle
$bar = get_post_meta('bar', $post_id, true);
The 2 lines of code above will trigger, at maximum, 1 database query.
In fact, when you query a custom field, all the fields for that post are retrieved from database, cached via object cache, and subsequent requests pull data from cache and not from db.
The same happen for taxonomy terms, WordPress pulls all the terms for a taxonomy once, then returns them from cache.
Object cache is used very widely in WordPress. Not only for posts, meta values and taxonomies, but also for users, comments, theme data...
WP_Query has to do with all of this?
When you query some posts via
WP_Query, by default, WordPress not only pulls them from database (or from cache if they are cached) but also updates the cache for all custom fields and all taxonomies related to the posts pulled.
So when you call, for example,
get_post_meta() while looping posts got via
WP_Query, you don't actually trigger any database query, but pull information from cache.
Nice, it isn't?
Well, yes, but it comes with a cost.
The cache update "magic" that WordPress does when pull posts via
WP_Query happen in
update_meta_cache for meta and in
update_object_term_cache for taxonomies.
If you look at the source code of those functions, you'll see that there WordPress performs just one db query in each function, but also does a lot of processing. For example, in
update_object_term_cache there are 7 nested
foreach... if you have a lot of taxonomies, and the number of posts per page is high, this is not very performant.
WP_Query arguments, finally
'update_post_term_cache' do when set to
false is to prevent WordPress to update cache for custom fields and taxonomies, respectively.
In that case, the first time a custom field or a taxonomy is queried a database query is triggered, and data are cached.
It worth the trouble?
As usual, the answer is it depends. Most of the times to set those values to
false, is a good choice, because it prevents unnecessary processing and database queries if not needed, and cache is updated anyway the first time custom field / taxonomy terms are required.
However, if you are going to call, even once,
get_post_meta() during the loop and you are going to call
get_the_terms() for all (or most) of the taxonomies supported by posts, then the cache updating is triggered anyway, and there might be no actual benefit on setting those query arguments to