-1

It was suggested to use a transient method to remove the duplicate queries Duplicate Queries

Why does this don't work? Is it the wrong way to use it

 private function get_acf_list()
  {
      if(!class_exists('acf')){
        return array();
      }
      global $wpdb;
      if ( false === ( $pgggo_qry = get_transient( 'pgggo_acf_query_results' ) ) ) {
        // It wasn't there, so regenerate the data and save the transient
        $pgggo_qry = "SELECT post_excerpt as 'field_name', post_title as 'field_label' FROM {$wpdb->prefix}posts where post_type = 'acf-field'";
        set_transient( 'pgggo_acf_query_results', $pgggo_qry, 12 * 7200 );
      }

      $pgggo_list_results = $wpdb->get_results($pgggo_qry, ARRAY_A);
      $acf_field_array    = array();
      if (!empty($pgggo_list_results)) {
          foreach ($pgggo_list_results as $value) {
              $acf_field_array[$value['field_name']] = $value['field_label'];
          }
      }
      return $acf_field_array;
  }
  • 1
    You're caching the wrong thing. You don't need to cache the literal string sent to the database, it's the results you want to cache. If you already have the results cached, use them instead of making a new query. I also don't see the reason for using a custom SQL query. Use a standard WP_Query loop instead and WP will store these in memory via WP_Cache in the same request already. Caching plugins can then intercept and cache the query for you. You throw all those optimisations away by using wpdb directly – Tom J Nowell Nov 10 at 23:28
  • @TomJNowell Thank you Tom, are you saying that I have to cache $pgggo_list_results variable? There is n't any proper method to list all the ACF custom fields. If i use the WP_Query method I have to loop through each post type and posts to generate the fields. get_field_objects in addition to that to retrive the post names. Which makes a heavy code than the SQL query. – Latheesh V M Villa Nov 11 at 10:06
  • @TomJNowell like this? $special_query_results = new \WP_Query( 'post_excerpt=field_name&post_title=field_label&post_type=acf-field' ); – Latheesh V M Villa Nov 11 at 10:15
  • Looping through them is fine, work done in PHP is work the database doesn't have to do, and if all that data has already been requested on that page load then no database work occurs at all. It's not heavier at all, it's just longer to type. Also avoid passing a string for your parameters when you can use an array – Tom J Nowell Nov 11 at 15:24
2

First, you don't need a raw SQL query, and by using one you give up all of WP's optimisations.

For example, if you run the query twice, it runs twice. If you had used WP_Query to getch those posts though, it would save them the first time to avoid making additional queries. It's even possible those posts are present as a result of other queries.

On top of that, caching plugins have limited options for working with your query, and you have to do all the validating/sanitising yourself.

So do something like this:

$q = new WP_Query(  [
    'post_type' => 'acf-field',
    'posts_per_page' => 50,
] );
if ( $q->have_posts() ) {
    while ( $q->have_posts() )  {
        $q->the_post();
        // ...
    }
    wp_reset_postdata();
}

Second, you don't need to faff around renaming columns and fetching individual fields. You're doing additional heavy lifting, and making it difficult to draw from already fetched data, and avoiding WP APIs.

Since your field_name is just the post excerpt, and your field_label is the post title, just use get_the_excerpt() and get_the_title() inside the loop.

The final result will naturally avoid duplicate queries, as WP will store what it fetched in WP_Cache and use it the second time around. If you install an object cache drop in with Redis/MemcacheD/etc, it'll avoid the query entirely.

A general rule of thumb in WP, is that if you need to do a raw SQL query to fetch data from anything other than a custom table, either something has gone terribly wrong, or you're making an incredibly expensive query that needs to go in a CLI command or a cron job.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.