site-logo

Speed up WP_Query requests to only return what is needed from the database

Here is a nice tip when you would like to speed up your database query for a given page. When you make a query for certain specific data in WordPress, WordPress by default will return ALL the data in an object. 95% of the time it is not required to return all the data from the database. It will just make your page loading slow especially if you have a WordPress Database that has taken on some fat. What you want WordPress to do is to STOP when it found the number of sufficient data/rows and not run around like a headless chicken on a black Friday sale collecting everything it possibly can.

Inside the WP_Query CLASS, class-wp-query.php(line 684) there exist a argument to assit with this:

@type bool $no_found_rows Whether to skip counting the total rows found. Enabling can improve performance. Default false.

Extraction from the code inside the class-wp-query.php where it test to see if the option was set when the query was passed.:

Line: 1806
// If true, forcibly turns off SQL_CALC_FOUND_ROWS even when limits are present.
		if ( isset($q['no_found_rows']) )
			$q['no_found_rows'] = (bool) $q['no_found_rows'];
		else
			$q['no_found_rows'] = false;


public function parse_query( $query = '' ) ...

Basically what it does is to NOT return all the rows. For example, if I only want to display 4x products in a certain category.

Very basic WordPress WP_Query request.:

<?php

$args = array(
'no_found_rows' => true,
// some more arguments
);

$db_query = new WP_Query( $args );

?>

Another example used in a loop in the Twenty Seventy Theme to only return 3x posts.:

<?php
			// Show recent blog posts if is blog posts page (Note that get_option returns a string, so we're casting the result as an int).
			if ( get_the_ID() === (int) get_option( 'page_for_posts' )  ) : ?>

				<?php // Show four most recent posts.
				$recent_posts = new WP_Query( array(
					'posts_per_page'      => 3,
					'post_status'         => 'publish',
					'ignore_sticky_posts' => true,
					'no_found_rows'       => true, ?
				) );
				?>

		 		<?php if ( $recent_posts->have_posts() ) : ?>

					<div class="recent-posts">

						<?php
						while ( $recent_posts->have_posts() ) : $recent_posts->the_post();
							get_template_part( 'template-parts/post/content', 'excerpt' );
						endwhile;
						wp_reset_postdata();
						?>
					</div><!-- .recent-posts -->
				<?php endif; ?>
			<?php endif; ?>
GO BACK : BLOG-PAGE