In general,
the query performed on the homepage,
query_posts( 'posts_per_page=get_option( 'posts_per_page' )
and
$q = new WP_Query( 'posts_per_page=get_option( 'posts_per_page' )
should have the same exact performance with very very little to no difference between them as all of the above are exactly the same by default (that is, have the same query arguments by default). This is because all of these queries uses the WP_Query
class to run build and run db queries to return the queried posts. get_posts()
is a bit faster although it also uses WP_Query
. The big difference is that get_posts
passes no_found_rows=true
to WP_Query
which legally breaks pagination.
What is true, the main query (primary query) runs on each and every page load according to the exact page being loaded. Removing the main loop and replacing it with a secondary query (either query_posts()
, WP_Query
or get_posts()
) is what is referred to as making the page slow. This is because you are doing the same work twice. As I said, the main query runs regardless, so you have already queried the db for posts, and replacing the main loop with a secondary query queries the db again.
Apart from issues created with pagination and other crappy issues, this is why one should never replace the main loop from the main query with a secondary one. I have done an extensive post on this which you can read here. To alter the main query, always use pre_get_posts
as it alters the query vars before the WP_Query
class builds and runs the SQL query. There are also other filters (post clause filters) available in WP_Query
which you can use to directly alter the SQL query
What makes query_posts
bad is that it alters the main query object on which many functions rely as query_posts
does the following
$wp_query = new WP_Query()
and it also alters the conditional tags. For a full explanation, you can read my answer here. A normal WP_Query
does not do that
query_posts
usersWP_Query
so it is a secondary query. If you need to usequery_posts
then use thepre_get_posts
hook instead which is much faster than a new database call. See the most famous answer in WPSE history! – Howdy_McGee♦ May 19 '16 at 20:46WP_Query
, this is the big boss. I just wanted to show there may not be a "big red button" bellowquery_posts
where it reads "Don't press here". – prosti May 19 '16 at 20:51WP_Query
, so is it also a secondary query ;-) – Pieter Goosen May 20 '16 at 10:59query_posts()
" mantra isn't (just) because it's slow; it's because it overwrites the main query and can cause unexpected results. See this answer for more details. – Pat J May 25 '16 at 2:20