web-dev-qa-db-ja.com

複雑なwp_queryを高速化する方法

私は bbPressフォーラム/トピックが読まれたかどうかをチェックするWordpressプラグインを作りました

基本的には、トピックが読み込まれると、ポストメタbbppu_read_byがトピックに追加されます。これは、値としてユーザーIDを持ちます。

それから私が読んだトピックスを入手したいのであれば(例えばここで、フォーラムID#3526とユーザー#1のために);これらの引数を持つカスタムクエリを使用します。

$read_query_args = array(
    'post_type'                 => 'topic',
    'post_parent'               => 3526,
    'posts_per_page'            => -1,
    'post_status'               => 'publish,closed,private',
    'meta_query' => array(
        //fetch only read posts
        array(
            'key'       => 'bbppu_read_by',
            'value'     => 1, //user ID
            'compare'   => '=',
        ),
        //ignore posts that are older than the user's registration time
        array(
            'key' => '_bbp_last_active_time',
            'value' => '2015-10-04 11:51:05',
            'compare' => '>',
        ),

    ),
    //try to optimize the query
    'fields'                    => 'ids', //get only IDs
    'no_found_rows'             => true, //https://wpartisan.me/tutorials/wordpress-database-queries-speed-sql_calc_found_rows
    'update_post_term_cache'    => false //ignore terms
);

これにより、次のクエリが生成されます。

SELECT wp_posts.ID FROM wp_posts INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) WHERE 1=1 AND wp_posts.post_parent = 3526 AND ( ( wp_postmeta.meta_key = '_bbp_last_active_time' AND wp_postmeta.meta_value > '2015-10-04 11:51:05' ) AND ( mt1.meta_key = 'bbppu_read_by' AND mt1.meta_value = '1' ) ) AND wp_posts.post_type = 'topic' AND ((wp_posts.post_status = 'publish' OR wp_posts.post_status = 'closed' OR wp_posts.post_status = 'private')) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC

PhPMyAdminでは、このクエリは約0.0393秒かかり、228件の投稿を返します。

Postmetaを使わずに同じクエリを実行すると0.0022秒しかかかりません。

SELECT wp_posts.ID FROM wp_posts WHERE 1=1  AND wp_posts.post_parent = 3526 AND wp_posts.post_type = 'topic' AND ((wp_posts.post_status = 'publish' OR wp_posts.post_status = 'closed' OR wp_posts.post_status = 'private')) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC 

これは大きな違いです。約18倍高速です。

私は、プラグインが遅いという不満をユーザに訴えています。彼は100.000+の投稿を持つフォーラムを持っています。

これを速くするための解決策があるかどうか私は思っていましたか?

1
gordie

ユーザーが読んだのはトピックではなくユーザーのプロパティです。ユーザーごとにこの情報が必要です。そのためにはユーザーのメタに値を格納する必要があります。現在のシステムが相互に排他的ではないためにトピックを読むユーザーを知りたいと思うかもしれませんが、概念的に悪いのは遅いということです。

1
Mark Kaplun