isucon 後の復習(といっても頭で考えてるだけで手を動かしてないけど)
サイドバーのクエリ
こういう中間テーブルを作ってまずそこから article id だけ引き実データを引くクエリをもう一回投げる、という考え方をした。
CREATE TABLE t ( a INT NOT NULL, t TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, KEY (t) ) ENGINE=InnoDB; INSERT INTO t SELECT ... (サイドバークエリの LIMIT なしのやつを一回走らせてデータを入れる SELECT * FROM t ... ORDER BY t LIMIT 10;
ここまでやったところ JOIN するもとのクエリと最後の中間テーブルから引くクエリで結果が違ってしまい混乱してしばらく悩んだ末諦めてしまったけど、 SELECT したとき時刻のカラムが DATETIME 型っぽい出力結果だったのが気になってて、なんとなく型があってないので CURRENT_TIMESTAMP で挿入されてしまって article id 順になっちゃっただけかなーといまは思う。 isucon.sql のほうで TIMESTAMP 型になってたけど実は DATETIME 型だった、とか、もしくは 5.5 だと TIMESTAMP 型でも SELECT したときの表現は DATETIME 型っぽくなるもので(おれが知らないだけ?) INSERT するときは適切に変換すべし、だったのかもしれない。
キャッシュと不整合チェック
これはぼけてただけかな、というきがするけどまだピンときてない感じもする。とりあえず GET / のみに限定して、素朴に「GET 時にキャッシュをみてなければ SET」「POST 時にキャッシュを破棄」っていうふうに書いて、 POST されたら破棄されるので POST 後の初回の GET で SET するようにすれば POST 1秒後の不整合チェックにはパスするよね?とか思ったんだけどやっぱ間違ってるのかな、書いててまた混乱してきた。
SSI がなぜ有効か
これは SSI を理解できてないからピンとこないのだろうなーということはぼんやりわかったきがする。 SSI 導入以前にいろいろ最適化済みであることが前提としてあるのかな。 SSI を使うにしても「サイドバーだけ組み立てて部分的な HTML を返すアプリの URL」とかを用意するわけじゃない、ってことなのかな。仮にそういう機能を作って SSI 実行時にサイドバー部分だけ app のその URL を叩いて HTML を生成させるとして、サイドバー作るクエリが重いんだから結局ページ全部作りなおすのに比べてそんなに高速化になるのかな?っていうあたりが疑問だったんだけど、そもそもそういうことをするためのものじゃないってことだろうか。あと POST 時にサイドバー部分だけキャッシュを作りなおして memached に入れる -> フロント nginx が memached から直接読む、というのはイメージできるけど残りの部分はどうやってキャッシュしてるの?というのもうまくイメージできない、穴抜けの HTML をキャッシュとかできるもんなのか?まさにそれを SSI がやってくれるのだということなのか・・・