Split the main WP_Query posts query into two queries to avoid temp tables. Leverage cache to avoid second query in persistent cache environments. Props scribu, cheald, prettyboymp. see #18536

git-svn-id: https://develop.svn.wordpress.org/trunk@19918 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Ryan Boren
2012-02-14 15:09:35 +00:00
parent 5055a133d5
commit 021c55798e
5 changed files with 88 additions and 25 deletions

View File

@@ -2606,9 +2606,11 @@ class WP_Query {
if ( !$q['no_found_rows'] && !empty($limits) )
$found_rows = 'SQL_CALC_FOUND_ROWS';
$this->request = " SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits";
if ( !$q['suppress_filters'] )
$this->request = apply_filters_ref_array('posts_request', array( $this->request, &$this ) );
$this->request = $old_request = "SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits";
if ( !$q['suppress_filters'] ) {
$this->request = apply_filters( 'posts_request', $this->request, $this );
}
if ( 'ids' == $q['fields'] ) {
$this->posts = $wpdb->get_col($this->request);
@@ -2626,7 +2628,29 @@ class WP_Query {
return $r;
}
$this->posts = $wpdb->get_results($this->request);
if ( $old_request == $this->request && "$wpdb->posts.*" == $fields ) {
// First get the IDs and then fill in the objects
$this->request = "SELECT $found_rows $distinct $wpdb->posts.ID FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits";
$this->request = apply_filters( 'posts_request_ids', $this->request, $this );
$ids = $wpdb->get_col( $this->request );
if ( $ids ) {
$this->set_found_posts( $q, $limits );
_prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
$this->posts = array_map( 'get_post', $ids );
} else {
$this->found_posts = $this->max_num_pages = 0;
$this->posts = array();
}
} else {
$this->posts = $wpdb->get_results( $this->request );
$this->set_found_posts( $q, $limits );
}
// Raw results filter. Prior to status checks.
if ( !$q['suppress_filters'] )
@@ -2645,13 +2669,6 @@ class WP_Query {
$this->comment_count = count($this->comments);
}
if ( !$q['no_found_rows'] && !empty($limits) ) {
$found_posts_query = apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) );
$this->found_posts = $wpdb->get_var( $found_posts_query );
$this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
$this->max_num_pages = ceil($this->found_posts / $q['posts_per_page']);
}
// Check post status to determine if post should be displayed.
if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) {
$status = get_post_status($this->posts[0]);
@@ -2754,6 +2771,18 @@ class WP_Query {
return $this->posts;
}
function set_found_posts( $q, $limits ) {
global $wpdb;
if ( $q['no_found_rows'] || empty( $limits ) )
return;
$this->found_posts = $wpdb->get_var( apply_filters( 'found_posts_query', 'SELECT FOUND_ROWS()', $this ) );
$this->found_posts = apply_filters( 'found_posts', $this->found_posts, $this );
$this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
}
/**
* Set up the next post and iterate current post index.
*