mirror of
https://github.com/WordPress/WordPress.git
synced 2024-11-04 18:01:42 +01:00
Split the comment query.
`WP_Comment_Query` now fetches comments in two stages: (1) a query to get the IDs of comments matching the query vars, and (2) a query to populate the objects corresponding to the matched IDs. The two queries are cached separately, so that sites with persistent object caches will continue to have complete cache coverage for normal comment queries. Splitting the query allows our cache strategy to be more modest and precise, as full comment data is only stored once per comment. It also makes it possible to introduce logic for paginated threading, which is necessary to address certain performance problems. See #8071. data is only stored once per comment, instead of along with Built from https://develop.svn.wordpress.org/trunk@34310 git-svn-id: http://core.svn.wordpress.org/trunk@34274 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
04f7a0da2f
commit
c6c9f8ad26
@ -34,6 +34,15 @@ class WP_Comment_Query {
|
|||||||
*/
|
*/
|
||||||
public $meta_query = false;
|
public $meta_query = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata query clauses.
|
||||||
|
*
|
||||||
|
* @since 4.4.0
|
||||||
|
* @access protected
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $meta_query_clauses;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date query container
|
* Date query container
|
||||||
*
|
*
|
||||||
@ -261,8 +270,6 @@ class WP_Comment_Query {
|
|||||||
public function get_comments() {
|
public function get_comments() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
$groupby = '';
|
|
||||||
|
|
||||||
$this->parse_query();
|
$this->parse_query();
|
||||||
|
|
||||||
// Parse meta query
|
// Parse meta query
|
||||||
@ -281,7 +288,7 @@ class WP_Comment_Query {
|
|||||||
// Reparse query vars, in case they were modified in a 'pre_get_comments' callback.
|
// Reparse query vars, in case they were modified in a 'pre_get_comments' callback.
|
||||||
$this->meta_query->parse_query_vars( $this->query_vars );
|
$this->meta_query->parse_query_vars( $this->query_vars );
|
||||||
if ( ! empty( $this->meta_query->queries ) ) {
|
if ( ! empty( $this->meta_query->queries ) ) {
|
||||||
$meta_query_clauses = $this->meta_query->get_sql( 'comment', $wpdb->comments, 'comment_ID', $this );
|
$this->meta_query_clauses = $this->meta_query->get_sql( 'comment', $wpdb->comments, 'comment_ID', $this );
|
||||||
}
|
}
|
||||||
|
|
||||||
// $args can include anything. Only use the args defined in the query_var_defaults to compute the key.
|
// $args can include anything. Only use the args defined in the query_var_defaults to compute the key.
|
||||||
@ -291,13 +298,66 @@ class WP_Comment_Query {
|
|||||||
$last_changed = microtime();
|
$last_changed = microtime();
|
||||||
wp_cache_set( 'last_changed', $last_changed, 'comment' );
|
wp_cache_set( 'last_changed', $last_changed, 'comment' );
|
||||||
}
|
}
|
||||||
$cache_key = "get_comments:$key:$last_changed";
|
$cache_key = "get_comment_ids:$key:$last_changed";
|
||||||
|
|
||||||
if ( $cache = wp_cache_get( $cache_key, 'comment' ) ) {
|
$comment_ids = wp_cache_get( $cache_key, 'comment' );
|
||||||
$this->comments = $cache;
|
if ( false === $comment_ids ) {
|
||||||
|
$comment_ids = $this->get_comment_ids();
|
||||||
|
wp_cache_add( $cache_key, $comment_ids, 'comment' );
|
||||||
|
}
|
||||||
|
|
||||||
|
// If querying for a count only, there's nothing more to do.
|
||||||
|
if ( $this->query_vars['count'] ) {
|
||||||
|
// $comment_ids is actually a count in this case.
|
||||||
|
return intval( $comment_ids );
|
||||||
|
}
|
||||||
|
|
||||||
|
$comment_ids = array_map( 'intval', $comment_ids );
|
||||||
|
|
||||||
|
if ( 'ids' == $this->query_vars['fields'] ) {
|
||||||
|
$this->comments = $comment_ids;
|
||||||
return $this->comments;
|
return $this->comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_prime_comment_caches( $comment_ids, $this->query_vars['update_comment_meta_cache'] );
|
||||||
|
|
||||||
|
// Fetch full comment objects from the primed cache.
|
||||||
|
$_comments = array();
|
||||||
|
foreach ( $comment_ids as $comment_id ) {
|
||||||
|
if ( $_comment = wp_cache_get( $comment_id, 'comment' ) ) {
|
||||||
|
$_comments[] = $_comment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter the comment query results.
|
||||||
|
*
|
||||||
|
* @since 3.1.0
|
||||||
|
*
|
||||||
|
* @param array $results An array of comments.
|
||||||
|
* @param WP_Comment_Query &$this Current instance of WP_Comment_Query, passed by reference.
|
||||||
|
*/
|
||||||
|
$_comments = apply_filters_ref_array( 'the_comments', array( $_comments, &$this ) );
|
||||||
|
|
||||||
|
// Convert to WP_Comment instances
|
||||||
|
$comments = array_map( 'get_comment', $_comments );
|
||||||
|
|
||||||
|
$this->comments = $comments;
|
||||||
|
return $this->comments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally to get a list of comment IDs matching the query vars.
|
||||||
|
*
|
||||||
|
* @since 4.4.0
|
||||||
|
* @access protected
|
||||||
|
*
|
||||||
|
* @global wpdb $wpdb
|
||||||
|
*/
|
||||||
|
protected function get_comment_ids() {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$groupby = '';
|
||||||
$where = array();
|
$where = array();
|
||||||
|
|
||||||
// Assemble clauses related to 'comment_approved'.
|
// Assemble clauses related to 'comment_approved'.
|
||||||
@ -471,14 +531,7 @@ class WP_Comment_Query {
|
|||||||
if ( $this->query_vars['count'] ) {
|
if ( $this->query_vars['count'] ) {
|
||||||
$fields = 'COUNT(*)';
|
$fields = 'COUNT(*)';
|
||||||
} else {
|
} else {
|
||||||
switch ( strtolower( $this->query_vars['fields'] ) ) {
|
|
||||||
case 'ids':
|
|
||||||
$fields = "$wpdb->comments.comment_ID";
|
$fields = "$wpdb->comments.comment_ID";
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$fields = "*";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$join = '';
|
$join = '';
|
||||||
@ -625,11 +678,11 @@ class WP_Comment_Query {
|
|||||||
$join = "JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID";
|
$join = "JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $meta_query_clauses ) ) {
|
if ( ! empty( $this->meta_query_clauses ) ) {
|
||||||
$join .= $meta_query_clauses['join'];
|
$join .= $this->meta_query_clauses['join'];
|
||||||
|
|
||||||
// Strip leading 'AND'.
|
// Strip leading 'AND'.
|
||||||
$where[] = preg_replace( '/^\s*AND\s*/', '', $meta_query_clauses['where'] );
|
$where[] = preg_replace( '/^\s*AND\s*/', '', $this->meta_query_clauses['where'] );
|
||||||
|
|
||||||
if ( ! $this->query_vars['count'] ) {
|
if ( ! $this->query_vars['count'] ) {
|
||||||
$groupby = "{$wpdb->comments}.comment_ID";
|
$groupby = "{$wpdb->comments}.comment_ID";
|
||||||
@ -677,35 +730,11 @@ class WP_Comment_Query {
|
|||||||
$this->request = "SELECT $fields FROM $wpdb->comments $join $where $groupby $orderby $limits";
|
$this->request = "SELECT $fields FROM $wpdb->comments $join $where $groupby $orderby $limits";
|
||||||
|
|
||||||
if ( $this->query_vars['count'] ) {
|
if ( $this->query_vars['count'] ) {
|
||||||
return $wpdb->get_var( $this->request );
|
return intval( $wpdb->get_var( $this->request ) );
|
||||||
|
} else {
|
||||||
|
$comment_ids = $wpdb->get_col( $this->request );
|
||||||
|
return array_map( 'intval', $comment_ids );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 'ids' == $this->query_vars['fields'] ) {
|
|
||||||
$this->comments = $wpdb->get_col( $this->request );
|
|
||||||
return array_map( 'intval', $this->comments );
|
|
||||||
}
|
|
||||||
|
|
||||||
$results = $wpdb->get_results( $this->request );
|
|
||||||
/**
|
|
||||||
* Filter the comment query results.
|
|
||||||
*
|
|
||||||
* @since 3.1.0
|
|
||||||
*
|
|
||||||
* @param array $results An array of comments.
|
|
||||||
* @param WP_Comment_Query &$this Current instance of WP_Comment_Query, passed by reference.
|
|
||||||
*/
|
|
||||||
$_comments = apply_filters_ref_array( 'the_comments', array( $results, &$this ) );
|
|
||||||
|
|
||||||
// Convert to WP_Comment instances
|
|
||||||
$comments = array_map( 'get_comment', $_comments );
|
|
||||||
|
|
||||||
wp_cache_add( $cache_key, $comments, 'comment' );
|
|
||||||
if ( '*' === $fields ) {
|
|
||||||
update_comment_cache( $comments, $this->query_vars['update_comment_meta_cache'] );
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->comments = $comments;
|
|
||||||
return $this->comments;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2376,6 +2376,30 @@ function update_comment_cache( $comments, $update_meta_cache = true ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds any comments from the given IDs to the cache that do not already exist in cache.
|
||||||
|
*
|
||||||
|
* @since 4.4.0
|
||||||
|
* @access private
|
||||||
|
*
|
||||||
|
* @see update_comment_cache()
|
||||||
|
*
|
||||||
|
* @global wpdb $wpdb
|
||||||
|
*
|
||||||
|
* @param array $comment_ids Array of comment IDs.
|
||||||
|
* @param bool $update_meta_cache Optional. Whether to update the meta cache. Default true.
|
||||||
|
*/
|
||||||
|
function _prime_comment_caches( $comment_ids, $update_meta_cache = true ) {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$non_cached_ids = _get_non_cached_ids( $comment_ids, 'comment' );
|
||||||
|
if ( !empty( $non_cached_ids ) ) {
|
||||||
|
$fresh_comments = $wpdb->get_results( sprintf( "SELECT $wpdb->comments.* FROM $wpdb->comments WHERE comment_ID IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) );
|
||||||
|
|
||||||
|
update_comment_cache( $fresh_comments, $update_meta_cache );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazy load comment meta when inside of a `WP_Query` loop.
|
* Lazy load comment meta when inside of a `WP_Query` loop.
|
||||||
*
|
*
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* @global string $wp_version
|
* @global string $wp_version
|
||||||
*/
|
*/
|
||||||
$wp_version = '4.4-alpha-34309';
|
$wp_version = '4.4-alpha-34310';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||||
|
Loading…
Reference in New Issue
Block a user