質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

474閲覧

Wordpressのカスタムフィールドでの検索で特定の条件を追加すると処理に時間がかかる理由または調査方法を教えてください

himawari39

総合スコア14

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

1グッド

1クリップ

投稿2022/05/20 04:14

編集2022/05/20 06:17

いつもお世話になっています。
Wordpressの記事をカスタムフィールドで絞り込む機能をつけたいと思っています。
こちらでご教示頂きながら、

php

1<?php 2 $args = array( 3 'meta_query' => array( 4 'relation' => 'AND', 5 array( 6 'key' => 'Wall', 7 'value' => $_GET["WallMin"], 8 'compare' => '>=', 9 'type' => 'NUMERIC', 10 ), 11 array( 12 'key' => 'Wall', 13 'value' => $_GET["WallMax"], 14 'compare' => '<=', 15 'type' => 'NUMERIC', 16 ), 17 18 array( 19 'key' => 'BT', 20 'value' => $_GET["BTMin"], 21 'compare' => '>=', 22 'type' => 'NUMERIC', 23 ), 24 array( 25 'key' => 'BT', 26 'value' => $_GET["BTMax"], 27 'compare' => '<=', 28 'type' => 'NUMERIC', 29 ), 30 array( 31 'key' => 'KT', 32 'value' => $_GET["KTMin"], 33 'compare' => '>=', 34 'type' => 'NUMERIC', 35 ), 36 array( 37 'key' => 'KT', 38 'value' => $_GET["KTMax"], 39 'compare' => '<=', 40 'type' => 'NUMERIC', 41 ), 42 43 ), 44); 45 46$my_query = new WP_Query($args); 47if ($my_query->have_posts()) : while ($my_query->have_posts()) : $my_query->the_post(); 48?> 49 50<?php the_title(); ?><?php the_post_thumbnail(); ?><?php the_excerpt(); ?> 51 52<?php endwhile; endif; wp_reset_postdata(); ?>

という検索だとすぐに結果が出てくるようになったのですが、

php

1<?php 2 $args = array( 3 'meta_query' => array( 4 'relation' => 'AND', 5 array( 6 'key' => 'Year', 7 'value' => $_GET["YearMin"], 8 'compare' => '>=', 9 'type' => 'NUMERIC', 10 ), 11 array( 12 'key' => 'Year', 13 'value' => $_GET["YearMax"], 14 'compare' => '<=', 15 'type' => 'NUMERIC', 16 ), 17 array( 18 'key' => 'Wall', 19 'value' => $_GET["WallMin"], 20 'compare' => '>=', 21 'type' => 'NUMERIC', 22 ), 23 array( 24 'key' => 'Wall', 25 'value' => $_GET["WallMax"], 26 'compare' => '<=', 27 'type' => 'NUMERIC', 28 ), 29 30 array( 31 'key' => 'BT', 32 'value' => $_GET["BTMin"], 33 'compare' => '>=', 34 'type' => 'NUMERIC', 35 ), 36 array( 37 'key' => 'BT', 38 'value' => $_GET["BTMax"], 39 'compare' => '<=', 40 'type' => 'NUMERIC', 41 ), 42 array( 43 'key' => 'KT', 44 'value' => $_GET["KTMin"], 45 'compare' => '>=', 46 'type' => 'NUMERIC', 47 ), 48 array( 49 'key' => 'KT', 50 'value' => $_GET["KTMax"], 51 'compare' => '<=', 52 'type' => 'NUMERIC', 53 ), 54 55 ), 56); 57 58$my_query = new WP_Query($args); 59if ($my_query->have_posts()) : while ($my_query->have_posts()) : $my_query->the_post(); 60?> 61 62<?php the_title(); ?><?php the_post_thumbnail(); ?><?php the_excerpt(); ?> 63 64<?php endwhile; endif; wp_reset_postdata(); ?>

のように

php

1array( 2 'key' => 'Year', 3 'value' => $_GET["YearMin"], 4 'compare' => '>=', 5 'type' => 'NUMERIC', 6 ), 7 array( 8 'key' => 'Year', 9 'value' => $_GET["YearMax"], 10 'compare' => '<=', 11 'type' => 'NUMERIC', 12),

を追加すると検索結果が表れるまで10秒程度かかってしまいます。
まだテスト段階で記事も2~3個の状況なのになぜこれを追加すると極端に時間が掛かるようになるのかわからず困っています。

カスタムフィールドの設定は「Advanced Custom Fields」というプラグインを利用しており、いずれのカスタムフィールドもタイプを数値にしてます。ラベル、名前、最小値、最大値が違うだけで、その他の設定は初期のままです。

php

1array( 2 'key' => 'Year', 3 'value' => $_GET["YearMin"], 4 'compare' => '>=', 5 'type' => 'NUMERIC', 6 ), 7 array( 8 'key' => 'Year', 9 'value' => $_GET["YearMax"], 10 'compare' => '<=', 11 'type' => 'NUMERIC', 12),

がない状態で

php

1echo $_GET["YearMin"];

を表示させて見ても表示に時間が掛かることはありません。

KazuhiroHatano様からご教示頂きましたQuery Monitorの計測結果は

Yearを追加してもしなくても
64Q遅いクエリー2重複クエリー4
PHPエラー(10notice,675deprected)
でした。

確認すべき場所、改善点、疑わしい点などご教示お願いいたします。

nekora👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

とりあえずQuery Monitorを入れて当該のSQLのコスト確認してみましょう

WordPressのMetaQueryはEAVで設計されてます
柔軟性と引き換えにパフォーマンスとかを犠牲にしてます

MetaQueryの条件が一つ増えるたびにJOIN句が増えていき
1行あたりの処理量・情報量が増えていきます

ある程度以上検索条件が複雑になる場合や何度も繰り返し検索を行うなどの場合は
検索処理を分割したり、PHP側でも検索処理の一部を担わせるなどの対応を考えた方がいいです

検索対象となりうる投稿タイプ・カテゴリの投稿を全て取得して
あとは各投稿についてget_post_customで全メタ情報を取得して
PHPでフィルタリングするようにする、などです

投稿2022/05/20 05:56

KazuhiroHatano

総合スコア7804

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

himawari39

2022/05/20 05:59

ご教示ありがとうございます。 検索条件ではなくて検索条件の数に問題がありそうという事ですね。 さっそくQuery Monitorで確認してみます。
himawari39

2022/05/20 06:15

計測をしてみました。Yearを追加してもしなくても 64Q 遅いクエリー2 重複クエリー4 PHPエラー(10notice,675deprected) でした。
KazuhiroHatano

2022/05/20 06:27

実行されたSQLとそれぞれにかかった時間も出ているかと思うのでそれも見てみてください 実は違ったということもありうるので 重くなっている原因が本当にSQLなのかの確認です 多分これだけの数の条件だと相当に長いSQL文になっているかと思います
himawari39

2022/05/20 07:04

おっしゃるとおり、 SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_postsの部分が0.15秒だったものが7.4秒になっており2つありました。 またWallを削除してYearを追加したものも上記クエリが0.15秒程度だったため条件数が処理を遅くしている問題で間違いなさそうです。 「検索対象となりうる投稿タイプ・カテゴリの投稿を全て取得して あとは各投稿についてget_post_customで全メタ情報を取得して PHPでフィルタリングするようにする、などです」 の方法を試させて頂きます。
himawari39

2022/05/21 00:03

もう少し時間が掛かりそうですが解決し次第ベストアンサーにさせて頂き締め切りたいと思います。
himawari39

2022/05/21 05:10

おかげさまで無事に0.15秒程度で検索できるようになりました。 ありがとうございました。
guest

0

まだhtmlの部分までは作っていませんが
KazuhiroHatano様にご教示頂き、
https://kinsta.com/jp/blog/wordpress-get_posts/
https://elearn.jp/wpman/function/get_post_custom.html
https://mmcd-web.sounds-stella.jp/8913/how-to-use-wp-fields-on-post/
を参考にさせていただいて0.15秒程度で目的の記事を検索できるようになりました。
ありがとうございました!

php

1 2<?php 3$args = array(); 4$my_posts = get_posts($args); 5 6foreach ($my_posts as $p) { 7 $multifield = get_post_custom($p->ID); 8 if (($_GET['YearMin'] <= $multifield['Year'][0]) && ($multifield['Year'][0] <= $_GET['YearMax']) && ($_GET['WallMin'] <= $multifield['Wall'][0]) && ($multifield['Wall'][0] <= $_GET['WallMax']) && ($_GET['BTMin'] <= $multifield['BT'][0]) && ($multifield['BT'][0] <= $_GET['BTMax']) && ($_GET['KTMin'] <= $multifield['KT'][0]) && ($multifield['KT'][0] <= $_GET['KTMax'])) { 9 echo $p->post_title; 10 } else { 11 echo "false"; 12 } 13}

投稿2022/05/21 05:10

himawari39

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問