继续我的previous question: “我的帖子循环”为每篇帖子生成2个查询:
SELECT * FROM wp_users WHERE ID = \'53\'
require(\'wp-blog-header.php\'), require_once(\'wp-includes/template-loader.php\'), include(\'/themes/BT/search.php\'), the_post, WP_Query->the_post, WP_Query->setup_postdata, get_userdata, get_user_by, WP_User::get_data_by #20 (0.1ms)
SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (53) ORDER BY umeta_id ASC
require(\'wp-blog-header.php\'), require_once(\'wp-includes/template-loader.php\'), include(\'/themes/BT/search.php\'), the_post, WP_Query->the_post, WP_Query->setup_postdata, get_userdata, get_user_by, WP_User->init, WP_User->for_blog, WP_User->_init_caps, get_user_meta, get_metadata, update_meta_cache #21 (0.2ms)
即使在我将模板代码缩小到一个简单的循环之后,也会发生这种情况:
if ( have_posts() ) : while ( have_posts() ) : the_post();
echo $post->ID . "<br />";
endwhile;
endif;
这是预期的吗
最合适的回答,由SO网友:TheDeadMedic 整理而成
虽然WordPress在循环(缩略图、post meta、术语)的db缓存方面做得很好,但它并没有预先缓存用户(作者)。
因此,如果在循环中的所有帖子中有5个不同的作者,那么就有10个查询(1个用于用户对象,1个用于用户的元缓存存储)。多亏了WP_Query::setup_postdata()
(由调用the_post()
) - 该行:
$authordata = get_userdata($post->post_author);
如果帖子作者已经在缓存中,没有db命中,这就是为什么你的循环中可以有来自5个作者的100篇帖子,而你仍然只能得到10个额外的查询。
要预先缓存循环中的所有用户,并且无论有多少不同的作者,都只能有2个查询,请执行以下操作:
function wpse_203912_the_posts( $posts, $wp_query ) {
if ( $wp_query->is_main_query() ) { // Remove this condition if you want to cache users whenever anywhere queries posts
$user_ids = wp_list_pluck( $posts, \'post_author\' );
cache_users( $user_ids );
}
return $posts;
}
add_filter( \'the_posts\', \'wpse_203912_the_posts\', 10, 2 );
关于
cache_users()
它只会影响未缓存用户的db,因此可以安全地重复调用它,而不用担心是否已经缓存了用户。