web-dev-qa-db-ja.com

最適化する方法 WP 何百万もの投稿のためのサイト

私は、カスタム投稿タイプを介して数百万件の投稿を作成する可能性が高い会社のWebサイトに取り組んでいます。彼らは祈りなので、基本的にフロントエンドのユーザーはフォームを介して短いフレーズを送信するだけです。会社が気にするのは投稿内容と投稿日だけです。このサイトはまだ立ち上がっておらず、すでに12万人以上の投稿があるので、何百万人と言ったとき私は本気で死んでいる。

だから、いくつかの最適化の質問:

  1. 500,000件の投稿があるカスタム投稿タイプに「おすすめ」というカテゴリがあるとします。注目のカテゴリーは500投稿のみです。おすすめの投稿に対してクエリを作成した場合、50万の投稿全体に対してクエリを実行するのですか、それとも500のおすすめの投稿のみをクエリするのですか。おすすめの最新の投稿10件のみを表示したい場合はどうすればよいですか。
  2. このカスタム投稿タイプをデータベースに保存するときに、サーバーリソースを削減するためにできることは何かあります。特に、投稿の内容と日付だけが必要な場合に限ります。
  3. カスタム投稿タイプを使うべきですか?それはWordPressの管理者にうまく統合されているので私は原則としてそれが好きですが、パフォーマンスに重大な不利があるなら私は私が別のことをすることができると思います。

私はこの規模でプロジェクトに取り組んだことは一度もないので、私はいつもよりもパフォーマンスについて少し心配しています。助けてくれてありがとう!

19

1.クエリbefore WP_Queryが実行されるように設定します。

データベースクエリを最小限に抑えようとするときには、クエリを変更する唯一の機会はもちろんSQLデータベースで実行される前なので、これは留意すべき最も重要なことのようです。

通常のクエリ
通常のクエリでは、WordPressはwp()関数を使用し、それが次に$wp->main( $query_vars )を呼び出します。コンディショナルタグからの「is_変数」は、それらをWP_Query->get_posts()に渡す前に設定されます。これはそれをMySQLデータベースクエリに変換し、最後にそれらを$ wp_queryオブジェクトに格納します。クエリが SQLデータベース で実際に実行される前にクエリをフィルタリングすることは可能です。

pre_get_postsアクションはこのプロセスにフックし、WP_Query->get_posts()に渡される前にクエリを変更することを可能にします。

たとえば、「おすすめ」カテゴリの投稿に対するクエリをフィルタ処理する場合は、add_action( 'pre_get_posts', 'your_function_name' );を使用し、in_category内にyour_function_name条件タグを含めます。

function your_function_name( $query ) {
    if ( $query->in_category( 'featured' ) && $query->is_main_query() ) {
        // Replace 123 with the category ID of the featured category.
        $query->set( 'cat', '123' );
    }
}
add_action( 'pre_get_posts', 'your_function_name' );

プラグインAPI /アクションリファレンス/ pre get posts"WordPress Codex を参照してください。

ページ要求
[おすすめ]カテゴリのアーカイブページなどのページテンプレートの場合、条件付きタグはpre_get_postsフィルタからは機能しません。たとえば、WP_Queryが実行されていないため、アーカイブページを確認するためにis_categoryを使用することはできません。

代わりに、ページリクエストのメインクエリをnew WP_Queryで変更する必要があります。これは$query = new WP_Query( 'cat=123' );のようになります。最初から適切な引数を設定してクエリを実行します。

クラスリファレンス/ WPクエリ"WordPress Codex を参照してください。

2.データベースに保存する

カスタム投稿タイプに関連する$ dataのみがwp_insert_post_dataに返されるようにするために、フィルタwp_insert_postを使用できます。カスタム投稿タイプを確認するための条件付きステートメントを必ず含めてください。
プラグインAPI /フィルターリファレンス/ wp投稿データの挿入"WordPress Codex

このフックはwp_insert_post関数によって呼び出されます。この関数は、カスタム投稿タイプを更新するときに wp_update_post によって呼び出されます。通常はドラフトを保存するか、投稿を公開します。

データベースで更新されるデータを削減することの最適化の意味については私が個人的に話すことはできませんが、自分でそれをベンチマークする必要があります。

3.カスタム投稿タイプは掲載結果に影響しますか。

私の経験では、カスタム投稿タイプはコンテンツを管理するための強力なツールです。私はそれがより少ないリソースを使用する方法でそれを可能にするすべての方法で投稿を管理する他の方法を知りません。私は個人的には可能な限り行われる問い合わせの数を減らす方法を見つけることに集中するでしょう。

パーマリンク構造に関連するパフォーマンス上の問題があり、数字ではなくテキストで始まるとヒットすることがありました。 3 これは、多数のページをホストしているサイトでは特に厄介でしたが、 WordPressバージョン3.3。

スラグは通常、パーマリンク構造の最初の部分であり、バージョン3.3より前のバージョンではパフォーマンスに影響を与えたかどうかにかかわらず、ここではパーマリンクを紹介しているだけです。それ以外の点では、私はカスタム投稿タイプの使用から生じるパフォーマンス上の問題を認識していません。

その他のパフォーマンスオプション

過渡現象
コード内でクエリを最小限に抑える代わりになるわけではありませんが、 set_transient を使用してクエリをしばらく保存しておくと、新しいクエリが不要になります。これは Dave Clementsのpost で使われている例です。また、投稿タイプが更新されたときはいつでも一時的なものを削除するためにsave_postアクションを追加することをお勧めします。

<?php // IN THE SPOTLIGHT QUERY
if( false === ( $its_query = get_transient( 'its_query' ) ) ) {
    $pttimestamp = time() + get_option('gmt_offset') * 60*60;
    $its_query = new WP_Query( array(
        'post_type' => 'spotlight',
        'posts_per_page' => 1,
            'post__not_in' => $do_not_duplicate,
        'meta_query' => array(
            array(
                'key' => '_hpc_spotlight_end_time',
                'value' => $pttimestamp,
                'compare' => '>'
            )
        )
    ) );
    set_transient( 'its_query', $its_query, 60*60*4 );
}
if( have_posts() ) { // HIDE SECTION IF NO CURRENT ITS FEATURE ?>
    // LOOP GOES HERE: NOT IMPORTANT TO EXAMPLE
<?php } ?>

より多くのクエリの最適化
Thomas Griffinが彼の Optimize WordPress Queries チュートリアルにいくつかの良いヒントを書いています。これが彼の提案の簡単なリストです:

  • サーバーがMemcachedのような永続的なキャッシュを使用していない場合は、1回限りのクエリで'cache_results' => falseを設定します。 1回限りのクエリは「少量のデータを表示するために使用されるクエリです。現在の投稿に関連するリンクされた投稿のタイトルを表示するだけでも、選択する投稿のドロップダウンを表示することもできます特定のオプション設定」

    彼の例:$query = get_posts( array( 'posts_per_page' => 1, 'cache_results' => false ) );

  • ページ区切りが不要な場合は'no_found_rows' => trueを設定します。これは「MySQLがページ分割を必要とするかどうかを確かめるために結果を数えるのを迂回するでしょう」。

    彼の例:$query = new WP_Query( array( 'posts_per_page' => 1, 'no_found_rows' => true ) );

  • 投稿IDをクエリするのは、'fields' => 'ids'get_postsが必要な場合だけです。これにより、返されるデータ量が大幅に削減されます。 Database Descriptionを見れば、投稿ごとにかなり多くなります。"WordPress Codex

    彼の例:$query = get_posts( array( 'posts_per_page' => 1, 'fields' => 'ids' ) );

最後のヒントに加えて、 get_post_field を使用して1つまたは少数の投稿フィールドしか必要としない場合にも、同じ理由を適用できます。

クエリがどのように機能するのかをしっかり理解することは不可欠です。クエリをより具体的にできるほど、SQLデータベースに要求される作業は少なくなります。これは、データベースクエリを管理するための膨大な数の可能性があることを意味します。カスタムクエリを実行する場所(管理ページなのか)に関しては慎重に行ってください。直接クエリでは適切な sanitization を使用し、同じパフォーマンスを達成できるネイティブのWordPress関数を使用してください。

23
iyrin

私はまた追加:

    'no_found_rows'          => true,
    'update_post_term_cache' => false,
    'update_post_meta_cache' => false,
    'cache_results'          => false
  • no_found_rows(ブール値) - ページ付けが不要で、見つかった投稿の総数のカウントが不要な場合はtrueにします。
  • cache_results(boolean) - ポスト情報キャッシュ。
  • update_post_meta_cache(boolean) - 投稿メタ情報キャッシュ。
  • update_post_term_cache(ブール値) - ポストターム情報キャッシュ。

これらのパラメータを使用し、値をFALSEとして渡すことで、余分なデータベースクエリが実行されないようにすることでクエリを高速化できます。

注:キャッシュに何かを追加するのが正しいため、これらのパラメーターを常に使用するべきではありません。ただし、特定の状況ではこれらのパラメーターが役立つ場合があります。

ご覧ください: https://drujoopress.wordpress.com/2013/06/27/how-to-optimize-wordpress-query-to-get-results-faster/#more-184

3
rigosan

時期尚早の最適化タイプの質問であるため、この質問には、実際に使用したときにしか発見されないことが多い正確な使用パターンを知らなければ、実際には答えられません。

一般に、MYSQLの仕様によれば、データ量に問題はないはずです。もちろん、最善のアルゴリズムでデータを検索するのは、はるかに小さいテーブルの場合より遅くなりますが、その解決策は単純で強力なCPUです。

メタデータの保存方法を最適化したい場合(たとえば、ping関連のデータを保存しない場合)、このようなことは実際の作業内容によって異なります。最終的にはまだ強力なCPUが必要なので、問題ないでしょう。 。

1
Mark Kaplun