参照メインのWordpressの場合はMySQLのクエリキャッシュを有効にすると幸せになるかもしれない


wordpressで技術的な内容をググろうと思うと難しくないっすか？？
pluginの使い方とかがいっぱい出てきますが、違う！！
「俺が欲しいのはそんな情報じゃねーーーー！！！」ってよく思います。

wordpressで参照メインのサイトに MySQLのクエリキャッシュを導入したら
幸せになれたのでその時の備考メモ

## 環境

* wordpress 4.5.3
* MySQL 5.5
* Amazon RDS db.m3.large

## 参考情報

* [MySQLリファレンス 8.9.3.4 クエリーキャッシュのステータスと保守](https://dev.mysql.com/doc/refman/5.6/ja/query-cache-status-and-maintenance.html)
* [MySQL のクエリキャッシュ周りの設定を確認/変更する方法](MySQL のクエリキャッシュ周りの設定を確認/変更する方法)
* [クエリキャッシュは切ったほうがいいんじゃなイカ？
](http://dsas.blog.klab.org/archives/52021866.html)


## generalログをみたらわかる小・中規模向けのCMSなwprdpress

実際は大規模でもそれなりきっと運用はできると思いますが、結構大変なイメージです。

トップページでのgeneralログをみてましょう。
(一部抜粋)

```
		  105 Query	SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'uninstall_plugins' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'ewww_image_optimizer_debug' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'ewww_image_optimizer_noauto' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'ewww_image_optimizer_webp_for_cdn' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'wpseo_onpage' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'ure_role_additional_options_values' LIMIT 1
		  105 Query	SELECT wp_redirection_items.*,wp_redirection_groups.position AS group_pos FROM wp_redirection_items INNER JOIN wp_redirection_groups ON wp_redirection_groups.id=wp_redirection_items.group_id AND wp_redirection_groups.status='enabled' AND wp_redirection_groups.module_id=1 WHERE (wp_redirection_items.regex=1 OR wp_redirection_items.url='/')
		  105 Query	select ID from wp_posts INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) where ( wp_postmeta.meta_key = "index_ad" AND CAST(wp_postmeta.meta_value AS CHAR) = "1") and post_status = "publish"
		  105 Query	SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  WHERE 1=1  AND wp_posts.ID NOT IN (88962,89034) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish')  ORDER BY wp_posts.post_date DESC LIMIT 0, 15
		  105 Query	SELECT FOUND_ROWS()
		  105 Query	SELECT wp_posts.* FROM wp_posts WHERE ID IN (92217,66743,21109,40658,26741,28233,40586,68212,35424,16449,14599,26698,19259,10428,10411)
		  105 Query	SELECT t.*, tt.*, tr.object_id FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id  WHERE tt.taxonomy IN ('category', 'post_tag', 'post_format', 'supervisor') AND tr.object_id IN (10411, 10428, 14599, 16449, 19259, 21109, 26698, 26741, 28233, 35424, 40586, 40658, 66743, 68212, 92217) ORDER BY t.name ASC
		  105 Query	SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (10411,10428,14599,16449,19259,21109,26698,26741,28233,35424,40586,40658,66743,68212,92217) ORDER BY meta_id ASC
		  105 Query	SELECT * FROM wp_users WHERE ID = '38'
		  105 Query	SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (38) ORDER BY umeta_id ASC
161109 16:47:38	  105 Query	SELECT wp_posts.* FROM wp_posts WHERE ID IN (92227,66873,22008,41707,31493,31400,40894,91872,89992,88478,14822,31198,87864,42795,55608)
		  105 Query	SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (14822,22008,31198,31400,31493,40894,41707,42795,55608,66873,87864,88478,89992,91872,92227) ORDER BY meta_id ASC
		  105 Query	SELECT * FROM wp_users WHERE ID = '26'
		  105 Query	SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (26) ORDER BY umeta_id ASC
		  105 Query	SELECT * FROM wp_users WHERE ID = '3'
		  105 Query	SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (3) ORDER BY umeta_id ASC
		  105 Query	SELECT * FROM wp_users WHERE ID = '20'
		  105 Query	SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (20) ORDER BY umeta_id ASC
		  105 Query	SELECT * FROM wp_users WHERE ID = '12'
		  105 Query	SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (12) ORDER BY umeta_id ASC
		  105 Query	SELECT * FROM wp_users WHERE ID = '30'
		  105 Query	SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (30) ORDER BY umeta_id ASC
		  105 Query	SELECT * FROM wp_users WHERE ID = '23'
		  105 Query	SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (23) ORDER BY umeta_id ASC
		  105 Query	SELECT * FROM wp_users WHERE ID = '4'
		  105 Query	SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (4) ORDER BY umeta_id ASC
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = '_transient_timeout_ga_ranking_30_3000' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = '_transient_ga_ranking_30_3000' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = '_transient_timeout_ga_ranking_all_2016-11-09' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = '_transient_ga_ranking_all_2016-11-09' LIMIT 1
		  105 Query	SELECT CONCAT('/', meta_value) as meta_value, post_id FROM wp_postmeta WHERE meta_key = 'custom_permalink'
		  105 Query	SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'uninstall_plugins' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'ewww_image_optimizer_debug' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'ewww_image_optimizer_noauto' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'ewww_image_optimizer_webp_for_cdn' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'wpseo_onpage' LIMIT 1
		  105 Query	SELECT option_value FROM wp_options WHERE option_name = 'ure_role_additional_options_values' LIMIT 1
```

これは抜粋したので一部です。

結構おおう・・・・って感じになりますよね・・・・


でもよーく見てましょう。
似たSQLを毎回発行しているのがわかりますよね？？？
そこで特にpluginのロードとかはほぼ固定でselectしていますよね。

そこでMysqlのオプション設定できる query_cacheを設定したら大分マシになるんじゃね？と思い設定してみました。

## 設定の前に

今のwordpressで運用しているサイトは参照が9割のサイトです。
例えばユーザーコメントとかが活発なサイトとかだと、キャッシュ更新の
頻度が上がって逆効果にもなりますのでご注意ください。
(あんまり更新が頻繁なwordpressのサイトも聞いたことないけども)

## 設定方法

### MySQL

```/etc/my.cnf
[mysqld]
.
.
.
query_cache_size = 512M
```

これだけ

### RDS

パラメーターグループをdefautl以外で設定していないと設定できないので注意してください

* RDS パラメーターグループの設定項目までいって編集
	* 自動化したいならaws-cliをつかってよしなに

下記の項目を追加

```
query_cache_limit  [バイト数]
query_cache_size   [バイト数]
```


これだけです。
適用タイプがdynamicなので無停止で反映できます。

パラメーターはメモリの2割位を割り当てました。


## 適用してみた

今までCPU使用率が 30-45%程度で推移していたのが一気に10%以下に

![RDS](https://raw.githubusercontent.com/ryurock/qiita_images/master/RDS_AWS_Console.png)


## 最後に

wordpressは結構アホみたいにSQLを発行します。
無駄なクエリはキャッシュさせることによってDB側の負荷を下げることができたりします。

ただしUPDATEを頻繁に行うサイトでは逆にパファーマンスは落ちるので注意してください。