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: http://svn.automattic.com/wordpress/trunk@19918 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
751ce362db
commit
6aedd9d0f0
|
@ -3703,3 +3703,26 @@ function wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pr
|
|||
else
|
||||
return $caller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve ids that are not already present in the cache
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param array $object_ids ID list
|
||||
* @param string $cache_key The cache bucket to check against
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function _get_non_cached_ids( $object_ids, $cache_key ) {
|
||||
$clean = array();
|
||||
foreach ( $object_ids as $id ) {
|
||||
$id = (int) $id;
|
||||
if ( !wp_cache_get( $id, $cache_key ) ) {
|
||||
$clean[] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
return $clean;
|
||||
}
|
||||
|
||||
|
|
|
@ -139,13 +139,7 @@ if ( !function_exists('cache_users') ) :
|
|||
function cache_users( $user_ids ) {
|
||||
global $wpdb;
|
||||
|
||||
$clean = array();
|
||||
foreach ( $user_ids as $id ) {
|
||||
$id = (int) $id;
|
||||
if ( !wp_cache_get( $id, 'users' ) ) {
|
||||
$clean[] = $id;
|
||||
}
|
||||
}
|
||||
$clean = _get_non_cached_ids( $user_ids, 'users' );
|
||||
|
||||
if ( empty( $clean ) )
|
||||
return;
|
||||
|
|
|
@ -64,13 +64,7 @@ function update_post_thumbnail_cache() {
|
|||
}
|
||||
|
||||
if ( ! empty ( $thumb_ids ) ) {
|
||||
get_posts( array(
|
||||
'update_post_term_cache' => false,
|
||||
'include' => $thumb_ids,
|
||||
'post_type' => 'attachment',
|
||||
'post_status' => 'inherit',
|
||||
'nopaging' => true
|
||||
) );
|
||||
_prime_post_caches( $thumb_ids, false, true );
|
||||
}
|
||||
|
||||
$wp_query->thumbnails_cached = true;
|
||||
|
|
|
@ -5318,3 +5318,26 @@ function _update_term_count_on_transition_post_status( $new_status, $old_status,
|
|||
wp_update_term_count( $tt_ids, $taxonomy );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds any posts from the given ids to the cache that do not already exist in cache
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param array $post_ids ID list
|
||||
* @param bool $update_term_cache Whether to update the term cache. Default is true.
|
||||
* @param bool $update_meta_cache Whether to update the meta cache. Default is true.
|
||||
*/
|
||||
function _prime_post_caches( $ids, $update_term_cache = true, $update_meta_cache = true ) {
|
||||
global $wpdb;
|
||||
|
||||
$non_cached_ids = _get_non_cached_ids( $ids, 'posts' );
|
||||
if ( !empty( $non_cached_ids ) ) {
|
||||
$fresh_posts = $wpdb->get_results( sprintf( "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE ID IN (%s)", join( ",", $non_cached_ids ) ) );
|
||||
|
||||
update_post_caches( $fresh_posts, 'any', $update_term_cache, $update_meta_cache );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue