###前提・実現したいこと
wordpress 4.5.2でカスタムフィールドで作成した記事が数万件あります。
このカスタムフィールドを
1.カスタムフィールドの名前順ソート
2.カスタムフィールドのあるなし判定
という条件で検索したいと考えています。
meta_queryで検索自体は実現したのですが、
データ量のせいか、検索に50秒ほどかかってしまい、実用に耐えない状況です。
Smart Custom Fieldを利用してカスタムフィールドを定義・データを入れているため、
post_metaにデータが入っていることまではわかったのですが、
インデックスの作成などチューニング手法で良い方法に出会えていません
###発生している問題・エラーメッセージ
meta_queryで検索自体は実現したのですが、
データ量のせいか、検索に50秒ほどかかってしまい、実用に耐えない状況です。
###該当のソースコード
PHP
1 $keyWords = $_GET['s']; 2 $post_type = 'shop_data'; 3 $searchArea = $_GET['searchArea']; 4 $searchCity = $_GET['searchCity']; 5 6 if($searchArea) { 7 $taxquery[] = array( 8 'taxonomy' => 'shop_area', 9 'terms' => $searchArea, 10 'field' => 'slug', 11 'operator' => 'AND' 12 ); 13 } 14 15 $taxquery['relation'] = 'AND'; 16 17 if($searchCity) { 18 $metaquery[] = array( 19 'key' => 'shop_city', 20 'value' => $searchCity, 21 'compare' => 'LIKE', 22 'operator' => 'OR' 23 ); 24 } 25 if( mb_strlen($keyWords)>0 ){ 26 $keyWordQuery[] = array( 27 'key' => 'shop_name', 28 'value' => mb_convert_kana($keyWords,'rsn'), 29 'compare' => 'LIKE', 30 'operator' => 'OR' 31 ); 32 $keyWordQuery[] = array( 33 'key' => 'shop_name', 34 'value' => mb_convert_kana($keyWords,'RSN'), 35 'compare' => 'LIKE', 36 'operator' => 'OR' 37 ); 38 $keyWordQuery[] = array( 39 'key' => 'shop_name', 40 'value' => mb_strtolower(mb_convert_kana($keyWords,'rsn')), 41 'compare' => 'LIKE', 42 'operator' => 'OR' 43 ); 44 $keyWordQuery[] = array( 45 'key' => 'shop_name', 46 'value' => mb_strtolower(mb_convert_kana($keyWords,'RSN')), 47 'compare' => 'LIKE', 48 'operator' => 'OR' 49 ); 50 $keyWordQuery[] = array( 51 'key' => 'shop_name', 52 'value' => mb_strtoupper(mb_convert_kana($keyWords,'rsn')), 53 'compare' => 'LIKE', 54 'operator' => 'OR' 55 ); 56 $keyWordQuery[] = array( 57 'key' => 'shop_name', 58 'value' => mb_strtoupper(mb_convert_kana($keyWords,'RSN')), 59 'compare' => 'LIKE', 60 'operator' => 'OR' 61 ); 62 $keyWordQuery[] = array( 63 'key' => 'shop_id', 64 'value' => mb_convert_kana($keyWords,'n'), 65 'compare' => '=', 66 ); 67 $keyWordQuery['relation'] = 'OR'; 68 $metaquery[] = $keyWordQuery; 69 } 70 $metaquery['relation'] = 'AND'; 71 72 $machine_meta[] = array( 73 'key' => 'p_data', 74 'value' => null, 75 'compare' => '!=' 76 ); 77 $machine_meta[] = array( 78 'key' => 's_data', 79 'value' => null, 80 'compare' => '!=' 81 ); 82 $machine_meta['relation'] = "OR"; 83 84 // p台データなし共通クエリ 85 $no_p_meta[] = array( 86 'key' => 'p_data', 87 'value' => null, 88 'compare' => '=' 89 ); 90 $no_p_meta[] = array( 91 'key' => 'p_data', 92 'compare' => 'NOT EXISTS' 93 ); 94 $no_p_meta['relation'] = "OR"; 95 96 // s台データなし共通クエリ 97 $no_s_meta[] = array( 98 'key' => 's_data', 99 'value' => null, 100 'compare' => '=' 101 ); 102 $no_s_meta[] = array( 103 'key' => 's_data', 104 'compare' => 'NOT EXISTS' 105 ); 106 $no_s_meta['relation'] = "OR"; 107 108 // 台データなし共通クエリ 109 $no_machine_meta[] = $no_p_meta; 110 $no_machine_meta[] = $no_s_meta; 111 $no_machine_meta['relation'] = "AND"; 112 113 // 取材IDあり 114 $report_meta = array( 115 'key' => 'report_exists', 116 'value' => true, 117 'type' => 'BOOLEAN', 118 'compare' => "=" 119 ); 120 121 // 取材IDなし 122 $no_report_meta[] = array( 123 'key' => 'report_exists', 124 'value' => false, 125 'type' => 'BOOLEAN', 126 'compare' => "=" 127 ); 128 $no_report_meta[] = array( 129 'key' => 'report_exists', 130 'value' => null, 131 'compare' => '=' 132 ); 133 $no_report_meta[] = array( 134 'key' => 'report_exists', 135 'compare' => 'NOT EXISTS' 136 ); 137 $no_report_meta['relation'] = "OR"; 138 139 // 1.台データURLあり/取材IDあり 140 $query1_meta = $metaquery; 141 $query1_meta[] = $machine_meta; 142 $query1_meta[] = $report_meta; 143 $query1 = new WP_Query (array( 144 'post_type' => $post_type, 145 'tax_query' => $taxquery, 146 'meta_query' => $query1_meta, 147 'posts_per_page' => -1, 148 'meta_key' => 'shop_name', 149 'orderby' => 'meta_value', 150 'order' => 'ASC' 151 )); 152 153 // 2.台データURLなし/取材IDあり 154 $query2_meta = $metaquery; 155 $query2_meta[] = $no_machine_meta; 156 $query2_meta[] = $report_meta; 157 $query2 = new WP_Query (array( 158 'post_type' => $post_type, 159 'tax_query' => $taxquery, 160 'meta_query' => $query2_meta, 161 'posts_per_page' => -1, 162 'meta_key' => 'shop_name', 163 'orderby' => 'meta_value', 164 'order' => 'ASC' 165 )); 166 167 // 3.台データURLあり/取材IDなし 168 $query3_meta = $metaquery; 169 $query3_meta[] = $machine_meta; 170 $query3_meta[] = $no_report_meta; 171 $query3 = new WP_Query (array( 172 'post_type' => $post_type, 173 'tax_query' => $taxquery, 174 'meta_query' => $query3_meta, 175 'posts_per_page' => -1, 176 'meta_key' => 'shop_name', 177 'orderby' => 'meta_value', 178 'order' => 'ASC' 179 )); 180 181 // 4.台データURLなし/取材IDなし 182 $query4_meta = $metaquery; 183 $query4_meta[] = $no_machine_meta; 184 $query4_meta[] = $no_report_meta; 185 $query4 = new WP_Query (array( 186 'post_type' => $post_type, 187 'tax_query' => $taxquery, 188 'meta_query' => $query4_meta, 189 'posts_per_page' => -1, 190 'meta_key' => 'shop_name', 191 'orderby' => 'meta_value', 192 'order' => 'ASC' 193 ));
###試したこと
- indexの作成
mysql> create index x_post_title ON wp_postmeta(post_id,meta_key(64),meta_value(64));
###補足情報(言語/FW/ツール等のバージョンなど)
PHP 5.3.3
MySQL 5.1.73
WordPress 4.5.2
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
DBのチューニングは不得意なので、私に出来る部分のみ指摘させていただきます。
まず、$query1から$query4までの結果セットの大部分は重複していることです。
取材IDの有無×台データ有無の4通り、ということは、表示の側で分岐すればDBへの問い合わせを3回減らすことが出来ます。表示側で4つに分ける処理はDBへの問い合わせよりは早いのではと思います。(予想なので、計測してみてください)
PHP
1$query0_meta = $metaquery; 2$query0 = new WP_Query (array( 3 'post_type' => $post_type, 4 'tax_query' => $taxquery, 5 'meta_query' => $query0_meta, 6 'posts_per_page' => -1, 7 'meta_key' => 'shop_name', 8 'orderby' => 'meta_value', 9 'order' => 'ASC' 10 ));
また、このクエリを取得する部分がどこに書かれているのか提示されていませんが、もし固定ページ/検索ページのテンプレート上に書かれている場合は、ページ自体のWP_Queryが発行された後になります。
ページ自体のWP_Queryの発行時に pre_get_posts
フィルタでご自身のクエリに書き換えることで、DBへの問い合わせを1回減らすことが出来ます。
【WordPressの新・旧ループからカスタムクエリ・アーカイブまで徹底解説 | OXY NOTES】
http://oxynotes.com/?p=8615
あとは、DBのキャッシュや表示のキャッシュをとることでも表示の高速化を図れると思います。(キャッシュの生成/破棄タイミングが案外難しいですが)
【W3 Total Cache -? WordPress Plugins】
https://wordpress.org/plugins/w3-total-cache/
投稿2016/06/25 06:16
総合スコア69407
0
MySQLのチューニングの前に念のためWordPressで行なっている4回のWP_Query($query1〜$query4)が全部遅いのか、特定の条件の場合にくなっているのか、これらを含む前後のコードも併せてmicrotime()
などでそれぞれの実行時間を出してみてはいかがでしょうか。(すべて遅いような気もしますが。。)
その上で、遅い処理に対してのMySQLのチューニングを
- クエリログなどから実際にWordPressがデータの検索時に発行しているクエリを確認
- EXPLAINなどで重いクエリの原因を調査
- 原因となっている部分をイデックスの作成などで改善
といった流れで行なっていくのが良いかと思います。
お使いの環境によってはそこまでいじれないよ、ということもあるかと思いますが、下記のような方法でスロークエリがわかるようにしておくより話が早いかもしれません。
WordPress全体をチューニングしていく際には、下記のような記事が参考になるかもしれません。
投稿2016/06/24 13:25
総合スコア121
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/06/24 19:13
2016/06/24 23:49
2016/06/25 03:54 編集
2016/06/25 03:49 編集
2016/06/25 03:49
2016/06/25 03:49
2016/06/25 03:53
2016/06/25 06:10
2016/06/25 06:55
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/06/25 07:11
2016/06/25 08:22