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:
You should never use
query_posts().
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_Queryfor an in-depth, flexible query script.
Reset/Cleanup
- Use
wp_reset_query()if you’ve usedquery_posts()or altered global$wp_querydirectly – hopefully you will never need to. - Use
wp_reset_postdata()if you’ve usedthe_post()orsetup_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_rowstotrue, making the query run dramatically faster. - When specific fields are not required, limit the returned fields to IDs:
'fields' => 'ids'
Top comments (0)