當(dāng)我們使用WordPress作為程序時(shí),如果WordPress網(wǎng)站的文章數(shù)量超過10萬,即使網(wǎng)站服務(wù)器的配置很強(qiáng)大,網(wǎng)站的打開速度基本上也會(huì)很慢。這時(shí)我們就需要對(duì)網(wǎng)站進(jìn)行優(yōu)化。
這是因?yàn)?WordPress 在查詢文章列表時(shí),默認(rèn)也會(huì)查詢文章數(shù)。這對(duì)于少量的網(wǎng)站數(shù)據(jù)應(yīng)該不會(huì)造成任何問題,但是對(duì)于大量的文章是不可避免的。慢查詢。主機(jī)引用的一位用戶告訴我們,他的網(wǎng)站有40萬篇文章,打開首頁需要一兩分鐘,甚至首頁或文章頁也經(jīng)常打不開。
WordPress網(wǎng)站查詢慢的原因:WordPress在查詢帖子列表時(shí),默認(rèn)也會(huì)查詢帖子數(shù)。使用此方法:get_posts、query_posts 和 WP_Query。get_posts在4.6.1+中沒有使用SQL_CALC_FOUND_ROWS,但是query_posts和WP_Query仍然使用,所以需要優(yōu)化。
那么如何解決WordPress文章過多導(dǎo)致網(wǎng)站慢的問題呢?
方法一:完全禁用SQL_CALC_FOUND_ROWS,將以下的代碼放到functions.php文件中:
add_action('pre_get_posts', 'miliol_post_filter');
function miliol_post_filter($query) {
// 確保這個(gè)過濾器只在前端的主查詢中應(yīng)用
if (is_admin() || !$query->is_main_query()) {
return;
}
// 禁用SQL_CALC_FOUND_ROWS
$query->set('no_found_rows', true);
}
方法二、如果您還需要查詢文章數(shù),請(qǐng)使用更高效的EXPLAIN方法代替SQL_CALC_FOUND_ROWS,以更高效的方式禁用SQL_CALC_FOUND_ROWS。這里我們使用 EXPLAIN 方法。
具體代碼如下,將以下的代碼放在functions.php文件中。
//優(yōu)化數(shù)據(jù)庫慢查詢
if ( ! function_exists( 'miliol_set_no_found_rows' ) ) {
/**
* 設(shè)置WP_Query的 'no_found_rows' 屬性為true,禁用SQL_CALC_FOUND_ROWS
*
* @param WP_Query $wp_query WP_Query實(shí)例
* @return void
*/
function miliol_set_no_found_rows(\WP_Query $wp_query)
{
$wp_query->set('no_found_rows', true);
}
}
add_filter( 'pre_get_posts', 'miliol_set_no_found_rows', 10, 1 );
if ( ! function_exists( 'miliol_set_found_posts' ) ) {
/**
* 使用 EXPLAIN 方式重構(gòu)
*/
function miliol_set_found_posts($clauses, \WP_Query $wp_query)
{
// Don't proceed if it's a singular page.
if ($wp_query->is_singular()) {
return $clauses;
}
global $wpdb;
$where = isset($clauses['where']) ? $clauses['where'] : '';
$join = isset($clauses['join']) ? $clauses['join'] : '';
$distinct = isset($clauses['distinct']) ? $clauses['distinct'] : '';
$wp_query->found_posts = (int) $wpdb->get_var("
SELECT COUNT(DISTINCT {$wpdb->prefix}posts.ID)
FROM {$wpdb->prefix}posts
$join
WHERE 1=1 $where
");
$posts_per_page = (!empty($wp_query->query_vars['posts_per_page']) ? absint($wp_query->query_vars['posts_per_page']) : absint(get_option('posts_per_page')));
$wp_query->max_num_pages = ceil($wp_query->found_posts / $posts_per_page);
return $clauses;
}
}
add_filter( 'posts_clauses', 'miliol_set_found_posts', 10, 2 );

評(píng)論