相も変わらずPCに向かっているここ数ヶ月。
マジで飽きてます。
というか、集中する為に他の業務を捨てているので、貯金が減る一方で溜まらなく心配である・・・。
で、今回は制作中のサイト『アマプロ』で10万間近という時に分かったボトルネックについてのメモ。
目次
記事数10万件を超える時はデータベース構造を見直したほうが良い?
大凡の予想はいたので、以前も一度取り組んだのですが、一部のアーカイブページで分かりやすく遅延が発生していたので再び取り組みました。
具体的にはデータベースの分割。
縦ファットよりは横ファット
正しいか分かりませんが、以前読んだ記事で、一定レベルであればレコード数を増大させるよりはカラム数を増やしたほうが速度低下は少ないとありました。
当然常識的な範囲で・・・。
ちなみに、全く逆で『レコード数を増やしても適切なSQL文を書けば大きなボトルネックにはならない』というのも何かで読みましたが、その時に見た説明は高度過ぎて良く分からなかったので(汗) 少なくとも最小限のレコード数とカラム数の組み合わせになるように再構築。
当然ですが、初期の設計って大切。
必要なモノを必要なだけJOIN
当然すぎる事ですが、必要な分だけJOINしたほうが効率的。
常に連結させるようなモノと、大して必要の無いモノは分けたほうが良い。
SQL文も見直す
データベースを見直したので当たり前だけど、SQL文はかなり見直した。
可能な限りNOT LIKEとかは使わずに処理出来るようにする。
5万件位まではワリと普通だったんだけど、8万件位から顕著に遅くなってた。
『order by』も遅延の原因になるのは以前から知ってたけど、使う必要もあるので『ダメだな』と思ったらINDEXを張る。
ALTER TABLE table_name ADD INDEX hoge (col1,col2)
indexが適切かも調べる。
EXPLAIN SELECT hoge FROM table_name ******
ちなみに、制作中のサイトでは必要と思われる個所全てにはINDEXを貼ってない。
今のところ、大きなボトルネックを感じてないから、どの程度まで行けるか見てから。
カテゴリやタグの扱いには注意
wordpressの場合、カテゴリとタグは同じテーブルを使います。
一つは名称などが入った【terms】。
記事との関連付けをする【term_relationships】。
カウントやタクソノミータイプを紐付ける【term_taxonomy】。
wp4.4から【termmeta】もあるけど、使ってないので今回は無視。
以前から感じてたけど、カテゴリやタグを自動で付与するようなプログラムを組むと【postmeta】同様に必然的に増大してしまう・・・。
私のサイトでは9万件の記事に対して、term_relationshipsに至っては44万レコードになってた。
termsもかなりのレコード数になっていたので、かなり気持ち悪い気がした。
その上、termsを使うと更新の為に発行するSQLが増える。
今回の場合、post_tagに 大して重要でも無いデータを置いていたので分離させた。
本質的なボトルネックを探る
遅いな?と感じたらやっぱり根っこを探るのが一番。
実際、今回もNOT LIkeが原因だったし。
今まで結構普通に動いてたから、『平気じゃね?』とか思ってたんですが、やっぱ遅いんですね。
余談
今回の見直しで、随分スムーズになったので10万件位は全然大丈夫でしょう。
細かい部分に手を入れてるモノのコアには手を付けて無い状態で維持出来ている。
特に考えなくてもobjectキャッシュも利用できるし、transientキャッシュみたいな便利機能も深く考えずに使えるWordpressサマサマです。
ただ、transientキャッシュに関しては、公式の説明通りに動かなかったので、取り出し方は変えてしまったけど・・・
汎用性も高く、便利スクリプトが非常に多いのでアプリケーションのコアとして使っても良いんじゃないかなー。
SSD系の高速で安いサーバーも増えてきたので、PHP使いの人でも色々やれる可能性は増えてる気がします。
次は20万件あたりどうなるかだなー。
100万件とかはAPIの兼ね合いで効率が落ちるので、そこまでは増えないように調整したいな。
ではでは