Multiple queries and performance – wp_query

No, the problem lies in the parts you didn’t put in your question, namely, the performance characteristics of a query are entirely down to this bit:

I have new WP_Query ($taxonomy_query) and then I run an if while:

That initial = new WP_Query([... is responsible for the entirety of the performance cost.

By the time the loop starts, the expensive part is already over. So no, your loop is fine, there is no room for optimisation here if you’re looking for performance gains. It’s what you’re querying for that determines the cost.

Then further down the page I use a foreach using:

$tax_countries = $taxonomy_query->posts;
foreach ($tax_countries as $option) {

I consider this suboptimal, it would be better to use a standard post loop instead, combined with the rewind_posts method to put the loop back at the start.

You also didn’t call have_posts on your query.

So, you should be able to do the following to run the same loop twice:

$q = new WP_Query([... arguments go here ...]);
if ( $q->have_posts() ) {
    while ( $q->have_posts() ) {
        $q->the_post();
        // do stuff
    }
    $q->rewind_posts();
    while ( $q->have_posts() ) {
        $q->the_post();
        // do other stuff
    }
    wp_reset_postdata();
} else {
    // nothing found
}

Nitpicking

  • Do 1 thing per line, don’t pile in all your if and while opening and closing clauses on the same line, it’s counterproductive and makes stuff harder to read
  • Stick to a standard post loop and WP_Query as much as possible, aint nobody got time for 4 or 5 functions that all call WP_Query anyway, with all their edge cases and caveats
  • Use { } syntax, it works much better with editors and automated tools, let your editor do all the heavy lifting ( which it can’t do if you use endwhile; etc )
  • If no posts were found, it still calls wp_reset_postdata even though there is no post data to reset! Put this after the loop but inside the if statement.
  • Use tabs to indent as the WP coding standards dictate, and let your editor indent for you. If you must use spaces, pick a coding standard and stick to it, but most importantly, be consistent. Again any half decent editor will do this for you
  • If you’re replacing the main query, instead of doing an extra query, use pre_get_posts instead