Minimising Database Queries in WordPress when using Advanced Custom Fields

I’m working on a page which lists staff members for a large company and trying to minimise the number of times I’m forced to query the database as it gets quite complex and slow.

  • 'person' is a custom post type (there are about 300 people)
  • 'date_accredited' is a date field added via Advanced Custom Fields plugin.

Only accredited staff will have a 'date_accredited'.

Read More

I need to list every 'person' BUT, with ALL accredited staff listed first (so about 20 accredited staff come at the top).

At the moment, I am doing a call to WP_Query like:

$args = array(
    'posts_per_page' => -1, 
    'post_type' => 'people', 
    'no_found_rows' => true, 
    'meta_key' => 'date_accredited'
);
$people = new WP_Query($args);

After that I’m doing:

while($people->have_posts()): $people->the_post();      
    $my_post_meta = get_post_meta($post->ID, 'date_accredited', true);
    if (!empty($my_post_meta)) {
        array_push($accredited, $post);
    } else {
        array_push($notAccredited, $post);
    }
endwhile;

Leaving us with two arrays of ‘person’ objects. My thinking here was that I would be able to do something like the following to get the list I want:

foreach($accredited as $person):
    personTile($person);
endforeach;

foreach($notAccredited as $person):
    personTile($person);
endforeach;

I’m trying to avoid re-querying the database.

The personTile(); function was supposed to output various info and HTML (the_post_thumbnail() and various Advanced Custom Fields fields), but what I’m realising now is that none of this is included in the post objects I get from WP_Query(), so I’m forced to use things like:

  • get_the_post_thumbnail($person->ID)
  • get_permalink($person->ID)
  • get_field('date_accredited', $person->ID)

All of these cost another DB Query (each!), and worse still since they are in a loop each one happens around 300 times.

Is there any way to get the permalink, thumbnail and ACF fields to be included in the original DB Query? Would I need to resort to a custom MySQL Query???

Any other suggestions welcome!

Related posts

Leave a Reply