简体   繁体   English

由元查询引起的Wordpress查询速度非常慢

[英]Very slow query on wordpress caused by meta query

I am trying to add in a slideshow 2 types of slides based on 2 different keys, just that the meta query is extremely slow. 我试图在幻灯片放映中基于2个不同的键添加2种类型的幻灯片,只是meta查询非常慢。 The wordpress query that I am using is: 我正在使用的wordpress查询是:

$args = array(
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key' => 'sgt_slide',
            'value' => 'on',
            'compare' => '='
        ),
        array(
            'key' => 'sgt_slide_home',
            'value' => 'on',
            'compare' => '='
        )
    ),
    'no_found_rows' => true, //exclude unnecessary paging calculations
    'numberposts' => -1,
    'post_status' => array( 'publish', 'inherit' ),
    'post_type' => array( 'post', 'attachment' )
    );
$slides = get_posts($args);

and the sql matching query that results is 和结果的sql匹配查询是

SELECT   nd_posts.* FROM nd_posts  INNER JOIN nd_postmeta ON (nd_posts.ID = nd_postmeta.post_id)
INNER JOIN nd_postmeta AS mt1 ON (nd_posts.ID = mt1.post_id) WHERE 1=1  AND nd_posts.post_type IN ('post', 'attachment') AND ((nd_posts.post_status = 'publish' OR nd_posts.post_status = 'inherit')) AND ( (nd_postmeta.meta_key = 'sgt_slide' AND CAST(nd_postmeta.meta_value AS CHAR) = 'on')
OR  (mt1.meta_key = 'sgt_slide_home' AND CAST(mt1.meta_value AS CHAR) = 'on') ) GROUP BY nd_posts.ID ORDER BY nd_posts.post_date DESC

This sql resulted query loads in 7 seconds, tested in phpmyadmin. 此sql导致查询加载在7秒钟内完成,并在phpmyadmin中进行了测试。 How can I overcome this. 我该如何克服这个问题。

EXPLAIN SQL 解释SQL

解释SQL

尝试将'cache_results' => false,添加到循环中

WordPress casts to char() which stops the index being used. WordPress强制转换为char(),这将停止使用索引。 The following code uses a filter to remove the cast: 以下代码使用过滤器删除演员表:

/**
 * Remove casting a meta_query to a char as this stops it using the index!
 */

function my_filter_meta_query( $pieces ) {
 if ( !empty( $pieces['where'] ) ) {
     // remove casting to CHAR as this is already a string
     $pieces['where'] = preg_replace("@CAST\(([^.]*.meta_value) AS CHAR\)@", "$1",$pieces['where']);
 }
return $pieces;
}

add_filter( 'get_meta_sql', 'my_filter_meta_query' );

More details http://www.topsemtips.com/2015/01/wordpress-meta-query-slow-wp_query/ 更多详细信息http://www.topsemtips.com/2015/01/wordpress-meta-query-slow-wp_query/

Ok fond how to solve it based on this: https://wordpress.stackexchange.com/questions/158898/meta-query-terribly-slow 好的,我喜欢如何基于此来解决它: https : //wordpress.stackexchange.com/questions/158898/meta-query-terribly-slow

function wpse158898_posts_clauses( $pieces, $query ) {
    global $wpdb;
    $relation = isset( $query->meta_query->relation ) ? $query->meta_query->relation : 'AND';
    if ( $relation != 'OR' ) return $pieces; // Only makes sense if OR.
    $prepare_args = array();
    $key_value_compares = array();
    foreach ( $query->meta_query->queries as $meta_query ) {
        // Doesn't work for IN, NOT IN, BETWEEN, NOT BETWEEN, NOT EXISTS.
        if ( ! isset( $meta_query['value'] ) || is_array( $meta_query['value'] ) ) return $pieces; // Bail if no value or is array.
        $key_value_compares[] = '(pm.meta_key = %s AND pm.meta_value ' . $meta_query['compare'] . ' %s)';
        $prepare_args[] = $meta_query['key'];
        $prepare_args[] = $meta_query['value'];
    }
    $sql = ' JOIN ' . $wpdb->postmeta . ' pm on pm.post_id = ' . $wpdb->posts . '.ID'
        . ' AND (' . implode( ' ' . $relation . ' ', $key_value_compares ) . ')';
    array_unshift( $prepare_args, $sql );
    $pieces['join'] = call_user_func_array( array( $wpdb, 'prepare' ), $prepare_args );
    $pieces['where'] = preg_replace( '/ AND[^' . $wpdb->postmeta[0] . ']+' . $wpdb->postmeta . '.*$/s', '', $pieces['where'] ); // Zap postmeta clauses.
    return $pieces;
}
add_filter( 'posts_clauses', 'wpse158898_posts_clauses', 10, 2 );
$slidess = new WP_Query($args);
$slides = $slidess->get_posts();
remove_filter( 'posts_clauses', 'wpse158898_posts_clauses', 10 );

And managed to imitate same pattern of get_posts with new WP_query and get_posts() function. 并使用新的WP_queryget_posts()函数模仿了相同的get_posts模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM