GP Web Dev

0 %
George Pattichis
Full-Stack Developer
Web Engineer
  • Residence:
    Cyprus
  • Studied in:
    Greece
  • Experience:
    +15 years
Frontend
Backend
Sysadmin
WordPress / WooCommerce
HTML / CSS
PHP / MySQL
JS / jQuery
Laravel / Symfony
Vue.js / React.js
  • Bootstrap, Bulma, Tailwind
  • Stylus, Sass, Less
  • Gulp, Webpack, Grunt
  • GIT / SVN knowledge
  • SCRUM certified PSM1
  • SEO / Core Web Vitals

WordPress Query Functions – What to use and when

February 26, 2021

WordPress Query Functions – What to use and when

Core WordPress functions and classes are generally excellent regarding to performance and security.

When it comes to retrieving data from the database, the WP_Query class and its methods provide us with a safe and efficient way to do it, avoiding complex SQL queries. There are some additional wrappers of WP_Query, like query_posts() and get_posts().

query_posts

WordPress Codex explicitly says “Its overly-simplistic approach to modifying the main query can be problematic and should be avoided wherever possible“.

This query wrapper is inefficient (re-runs SQL queries) and will fail in some circumstances, especially when dealing with posts pagination. It instantiates a new WP_Query object and reassigns that to the global wp_query, breaking the main query that many plugins, themes and custom scripts rely on. For secondary queries (custom loops) instantiate your own WP_Query.

Use new WP_Query or get_posts() which are pretty much interchangeable (latter is thin wrapper for former). If you do want to alter the main query, then use the pre_get_posts hook with $query->is_main_query() check. pre_get_posts is a filter for altering any query and it is most often used to alter the ‘main query’. This is the trac about the deprecation of query_posts.

Therefore:

get_posts

This is essentially a wrapper for a separate instance of a WP_Query object. This isn’t a ‘Loop’, it simply returns an array of post objects.

It accepts the same arguments as WP_Query, doesn’t modify global variables and is safe to use anywhere. It passes 'no_found_rows' => true by default so it is used for non paginated queries only. It ignores sticky posts, needs just a foreach loop to display the $post property and requires a setup_postdata( $post ) to make the template tags available. WP_Query uses the loop and template tags are available by default.

  • Use get_posts() for some quick, non-paginated, data fetch.

WP_Query

WP_Query is the class behind both the above functions. The power of WP_Query derives from the possibility to create and work with your own instance of it. It is more of a general purpose tool, similar to directly writing MySQL, for a detailed custom query script.

A bit more complex with fewer restrictions, thus making it more powerful while being safe to use anywhere.

  • Use a new WP_Query for an in-depth, flexible query script.

Reset/Cleanup

  • Use wp_reset_query() if you’ve used query_posts() or altered global $wp_query directly – hopefully you will never need to.
  • Use wp_reset_postdata() if you’ve used the_post() or setup_postdata() to restore initial state of global $post.

Performance

All queries are eventually wrappers of WP_Query, and while some are better than other (never use query_posts), the performance differences of get_posts vs WP_Query are negligible. The WP_Query is faster than get_posts by a very small margin.

However parameters provided by the WP_Query class can specifically optimize SQL queries, reducing execution time and resource consumption. (Ref. 1 | 2)

  • When we don’t need pagination, we should set no_found_rows to true, making the query run dramatically faster.
  • When specific fields are not required, limit the returned fields to IDs: 'fields' => 'ids'

Posted in Web Dev