Whilst WordPress has gotten pretty good at db caching for loops (thumbnails, post meta, terms), it does not pre-emptively cache users (authors).
So if you have 5 different authors across all the posts in your loop, that’s 10 queries (1 for the user object, 1 for the user’s meta cache stash). It’s thanks to WP_Query::setup_postdata()
(which is called by the_post()
) – this line:
$authordata = get_userdata($post->post_author);
If the post author is already in the cache, no db hit, which is why you could have 100’s of posts in your loop from 5 authors and you’d still only end up with 10 additional queries.
To pre-emptively cache all users in the loop and only ever have 2 queries, no matter how many different authors:
function wpse_203912_the_posts( $posts, $wp_query ) {
if ( $wp_query->is_main_query() ) { // Remove this condition if you want to cache users whenever anywhere queries posts
$user_ids = wp_list_pluck( $posts, 'post_author' );
cache_users( $user_ids );
}
return $posts;
}
add_filter( 'the_posts', 'wpse_203912_the_posts', 10, 2 );
The great thing about cache_users()
is that it will only hit the db for uncached users, so it’s safe to repeatedly call it without worrying if you’ve already cached the user.