ホームページクエリを削除する


8

home.phpテンプレートを表示するホームページに、ウィジェットを含む2つのサイドバーが含まれています。

メインクエリは引き続き標準の10件の投稿を取り込みますが、これらを表示していないため、データベースに対して行われるクエリを完全に削除します。必要に応じて、home.phpテンプレートでメインループを使用していないので、空のポストループで十分です。

どうすればいいですか?pre_get_postsクエリを最小化および削減するために使用できますが、それでも非常に高速なクエリが残ります。どうすれば完全に削除できますか?


1
この質問は読む価値があるようです。しかし、あなたが私に尋ねた場合、私は自分のテンプレートを使用し、それを設定から静的ホームページとして設定します。それは可能ではありますが、それだけの価値はないからです。ここでより興味深い読書。そのすべてか、私はあなたの質問の要点を完全に逃した。
N00b 2016年

回答:


7

posts_requestフィルタ

ざっと見てWP_Queryみると、この興味深い部分が見つかります。

if ( !$q['suppress_filters'] ) {
    /**
     * Filter the completed SQL query before sending.
     *
     * @since 2.0.0
     *
     * @param array    $request The complete SQL query.
     * @param WP_Query &$this   The WP_Query instance (passed by reference).
     */
      $this->request = apply_filters_ref_array( 'posts_request', 
          array( $this->request, &$this ) );
   }

   if ( 'ids' == $q['fields'] ) {
       $this->posts = $wpdb->get_col( $this->request );
       $this->posts = array_map( 'intval', $this->posts );
       $this->post_count = count( $this->posts );
       $this->set_found_posts( $q, $limits );
       return $this->posts;
   }

posts_requestフィルターを使用してメインのホームリクエストを排除しようとする場合があります。次に例を示します。

add_filter( 'posts_request', function( $request, \WP_Query $q )
{
    // Target main home query
    if ( $q->is_home() && $q->is_main_query() )
    {
        // Our early exit
        $q->set( 'fields', 'ids' );

        // No request
        $request = '';
    }

    return $request;    

}, PHP_INT_MAX, 2 );

ここで、強制的'fields' => 'ids'に早期終了します。

posts_pre_queryフィルタ(WP 4.6+)

WordPress 4.6以降で利用可能な新しいposts_pre_querysrcフィルターを使用することもできます

add_filter( 'posts_pre_query', function( $posts, \WP_Query $q )
{
    if( $q->is_home() && $q->is_main_query() )
    {
        $posts = [];
        $q->found_posts = 0;
    }
    return $posts;
}, 10, 2 );

このフィルターにより、通常のデータベースクエリをスキップして、代わりにカスタムのポストインジェクションを実装できます。

私はこれをテストしましたが、これはposts_requestアプローチとは逆に、固定投稿を防止しないことに気づきました。

詳細と@boonebgorgesによるについては、チケット#36687をチェックしてください。


先ほど書いたものとよく似ていますが、fields idsの部分を見つけられなかったため、さらに2つのクエリが実行されませんでした。ありがとうございます。
トムJノーウェル

1
大丈夫です、時々それはWP_Query、例えば、のような議論を通して、'skip_query' => trueあるいはフィルターを通してさえ、早期 に終了する簡単な方法を持っていることがどれほど素晴らしいことになるかと思いますが、それから私はそれがインターネット上のサイトをめちゃくちゃにすることがどれほど簡単にできるかを理解します。多くの方法;-) @TomJNowell
バージリー

split_the_query行のすぐ下にフィルターがありますが、まったく同じことを行いますが、クエリの数を減らしません!
スミット

私が見逃したとしても素晴らしい解決策であり'fields' => 'ids'、私はそれをよく使用しています;-)
Pieter Goosen

2

ここで私たちは付加することにより、メインクエリを停止することができ、@birgireから学んだ巧妙なトリックであるAND where 0=1WHERESQLクエリの句が。これでも1つのdbクエリが発生する可能性がありますが、メインクエリによる投稿のクエリは確実に停止します

add_filter( 'posts_where', function ( $where, \WP_Query $q )
{
    if (    $q->is_home()
         && $q->is_main_query()
    ) {
        $where .= ' AND where 0 = 1';
    }

    return $where;
}, 10, 2 ); 

WHERE句を次のように置き換えることもできますwhere 0 = 1

$where = ' where 0 = 1';

の代わりに

$where .= ' AND where 0 = 1';

残念ながら、私には何もテストする時間はありませんが、これは良い出発点になるはずです


これは、私が求めたもの、または少なくとも最も高度に最適化されたクエリに到達できる最も近いように思えます。クエリ自体を根絶できるかどうかを調査するときに、これを検討します
トムJノウェル

このアイデアを共有するための+1。しかし、私はそれをテストし、それは時間を2ミリ秒短縮します:)
Sumit

どこから学んだか思い出せたらいいのですが、これはコアでも使用されています;-)念のため、付箋も無視したほうがいいと思います$q->set( 'ignore_sticky_posts', true );
バージィ2016年

@birgireグレートスポット。私の解決策を使用しても、メインクエリからスティッキを取り戻す;-)
Pieter Goosen

2

参考までに、前:45q、後:42q

このコードは、@ birgireが使用するコードと非常によく似ています。

function _tomjn_home_cancel_query( $query, \WP_Query $q ) {
    if ( !$q->is_admin() && !$q->is_feed() && $q->is_home() && $q->is_main_query() ) {
        $query = false;
        $q->set( 'fields', 'ids' );
    }
    return $query;
}
add_filter( 'posts_request', '_tomjn_home_cancel_query', 100, 2 );
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.