isuconで学ぶ webアプリケーションのパフォーマンス向上のコツ...
DESCRIPTION
TRANSCRIPT
![Page 1: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/1.jpg)
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ
実践編 完全版ISUCON夏期講習
2014/8/20Masahiro Nagano
![Page 2: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/2.jpg)
この資料を読む前に以下の記事をお読みください
http://blog.nomadscafe.jp/2014/08/isucon-2014-ami.html
![Page 3: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/3.jpg)
チューニングにあたり@acidlemon さんのblog記事を参考にしています
「ざっくりと #isucon 2013年予選問題の解き方教えます」
http://isucon.net/archives/32976287.html
![Page 4: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/4.jpg)
挑戦してみました
![Page 5: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/5.jpg)
最終スコア
9079
![Page 6: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/6.jpg)
やってみたことを紹介します
![Page 7: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/7.jpg)
初期スコア
1664ruby実装にて
![Page 8: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/8.jpg)
(1) 環境整備
![Page 9: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/9.jpg)
静的コンテンツをReverse Proxy で配信
Reverse Proxy: クライアントからの接続を受け、Applicationサーバに処理を中継する。画像,js,css などの静的コンテンツを返す役割もある
Application Server: ユーザからのリクエストを受けて適切なページを構築・レスポンスを行う
![Page 10: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/10.jpg)
<VirtualHost *:80> DocumentRoot /home/isu-user/isucon/webapp/public RewriteEngine on RewriteCond REQUEST_URI !^/favicon\.ico$ RewriteCond REQUEST_URI !^/(img|css|js)/ RewriteRule /(.*)$ http://localhost:5000/$1 [P]</VirtualHost>
/etc/httpd/conf.d/isucon.conf
![Page 11: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/11.jpg)
スコア
1664 => 1719
![Page 12: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/12.jpg)
Nginx 化
• オープンソースのWebサーバ。高速に動作し、メモリ使用量がすくないなどの特徴があります
![Page 13: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/13.jpg)
Apache vs. Nginx
worker worker worker
worker worker worker
worker worker worker
リクエスト
コンテキストスイッチが大量発生
リクエスト
worker
1個のプロセスで効率よく通信を処理
![Page 14: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/14.jpg)
$ sudo yum install nginx$ sudo service httpd stop
[program:nginx]directory=/command=/usr/sbin/nginx -c /home/isu-user/isucon/nginx.confautostart = true
command
run.ini
nginx.conf: https://gist.github.com/kazeburo/7b0385cce1b0a4565581
![Page 15: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/15.jpg)
スコア
1719 => 1764
![Page 16: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/16.jpg)
(2) Perl にしますワタシハパールチョットデキル
![Page 17: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/17.jpg)
Perl の起動方法
command=/home/../isucon/env.sh carton exec --\ start_server --path /tmp/app.sock -- \ plackup -s Starlet \ --max-workers 4 \ --max-reqs-per-child 50000 \ -E production -a app.psgi
run.iniTCPではなくUNIX domain
socketを使う
プロセスを長生きさせる
プロセスはあげすぎない
![Page 18: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/18.jpg)
TCPの接続は高コスト
ReverseProxy
AppServer
リクエスト毎にthree way handshake
![Page 19: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/19.jpg)
スコア
1764 => 1891
![Page 20: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/20.jpg)
(3) アプリをみよう
![Page 21: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/21.jpg)
“/” “/recent/xxx”
“/memo/xxxx” “/mypage”
![Page 22: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/22.jpg)
“/” “/recent/xxx”
“/memo/xxxx” “/mypage”
DBへの問い合わせが重い
markdown の変換にプロセス起動
DBへの問い合わせが若干重い
![Page 23: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/23.jpg)
(4) 外部プロセス起動
![Page 24: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/24.jpg)
+use Text::Markdown::Hoedown qw//;
sub markdown { my $content = shift;- my ($fh, $filename) = tempfile();- $fh->print(encode_utf8($content));- $fh->close;- my $html = qx{ ../bin/markdown $filename };- unlink $filename;- return $html;+ Text::Markdown::Hoedown::markdown($content) }
webapp/perl/lib/Isucon3/Web.pm
ここがmarkdownコマンドを起動している
“/memo/xxxx”
XS(C)で高速にmarkdownを処理するモジュール
![Page 25: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/25.jpg)
スコア
1891 => 2233
![Page 26: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/26.jpg)
(5) N+1 クエリ
![Page 27: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/27.jpg)
my $memos = $self->dbh->select_all( 'SELECT * FROM memos WHERE is_private=0 ORDER BY created_at DESC, id DESC LIMIT 100');
for my $memo (@$memos) { $memo->{username} = $self->dbh->select_one( 'SELECT username FROM users WHERE id=?', $memo->{user}, );}
webapp/perl/lib/Isucon3/Web.pm
100回ルーーーープ
“/”
![Page 28: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/28.jpg)
use the join, luke
![Page 29: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/29.jpg)
id user_id id name
memosテーブル usersテーブル
id user_id name
memos JOIN users ON memos.user_id = user.id
![Page 30: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/30.jpg)
my $memos = $self->dbh->select_all( 'SELECT memos.*,users.username FROM memos JOIN users ON memos.user = users.id WHERE memos.is_private=0 ORDER BY memos.created_at DESC, memos.id DESC LIMIT 100');
webapp/perl/lib/Isucon3/Web.pm
“/”, “/recent”
![Page 31: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/31.jpg)
スコア
2233 => 2398
![Page 32: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/32.jpg)
(6) インデックス
![Page 33: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/33.jpg)
SELECT * FROM memos WHERE is_private=0 ORDER BY created_at DESC LIMIT 100
id is_private
...
0
0
1
0
1
memosテーブル
id is_private
...
0
0
0
ソート
webapp/perl/lib/Isucon3/Web.pm
indexがないと
抽出
CPU負荷高い
![Page 34: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/34.jpg)
indexをつくる
cat <<'EOF' | mysql -u isucon isuconALTER TABLE memos ADD INDEX (is_private,created_at);EOF
init.sh
![Page 35: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/35.jpg)
B-Tree
0 1is_private
created_at
older newer older newer
![Page 36: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/36.jpg)
B-Tree
0 1is_private
created_at
older newer older newer
![Page 37: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/37.jpg)
B-Tree
0 1is_private
created_at
older newer older newer
![Page 38: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/38.jpg)
B-Tree
0 1is_private
created_at
older newer older newer
![Page 39: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/39.jpg)
B-Tree
0 1is_private
created_at
older newer older newer
順に取得するだけ
![Page 40: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/40.jpg)
スコア
2398 => 2668
![Page 41: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/41.jpg)
(7) タイトル事前生成
![Page 42: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/42.jpg)
これ
![Page 43: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/43.jpg)
mysql> show create table memos\G*************************** 1. row *************************** Table: memosCreate Table: CREATE TABLE `memos` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user` int(11) NOT NULL, `content` text, `is_private` tinyint(4) NOT NULL DEFAULT '0', `created_at` datetime NOT NULL, `updated_at` timestamp NOT NULL DEFAULT, PRIMARY KEY (`id`),) ENGINE=InnoDB AUTO_INCREMENT=41311 DEFAULT CHARSET=utf81 row in set (0.00 sec)
mysql
titleカラムが存在しない!
![Page 44: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/44.jpg)
<: $memo.content.split('\r?\n').first() :>webapp/perl/views/index.tx
splitでCPU使用contentの転送で通信
タイトルは本文から都度生成
![Page 45: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/45.jpg)
cat <<'EOF' | mysql -u isucon isuconALTER TABLE memos ADD COLUMN title text;UPDATE memos SET title = substring_index(content,"\n",1);EOF
init.sh
titleカラムの追加し、事前生成
![Page 46: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/46.jpg)
POST時にも生成$self->dbh->query( 'INSERT INTO memos
(user, title, content, is_private, created_at) VALUES (?, ?, ?, ?, now()) ', $user_id, (split /\r?\n/, $content)[0], $content, $is_private,);
webapp/perl/lib/Isucon3/Web.pm
![Page 47: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/47.jpg)
my $memos = $self->dbh->select_all( 'SELECT memos.id, memos.title, memos.is_private, memos.created_at, users.username FROM memos JOIN users ON memos.user = users.id WHERE memos.is_private=0 ORDER BY memos.created_at DESC, memos.id DESC LIMIT 100');
webapp/perl/lib/Isucon3/Web.pm
“/”, “/recent”memos.* だと contentを取ってしまう
![Page 48: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/48.jpg)
スコア
2668 => 3060
![Page 49: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/49.jpg)
(8) OFFSET = 破棄
![Page 50: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/50.jpg)
SELECT * FROM memos ORDER BY created_at LIMIT 100
OFFSET 10000とても大きなOFFSET
”/recent/100”100ページ目
![Page 51: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/51.jpg)
MySQLのOFFSET処理のイメージ
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... .
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... .
1 2 3 4
5 6 7 8
9 10 11 12
13
10000
10001 10002 10003 10004
![Page 52: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/52.jpg)
MySQLのOFFSET処理のイメージ
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... .
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... .
1 2 3 4
5 6 7 8
9 10 11 12
13
10000
10001 10002 10003 10004
頑張ってソート
必要な個数まで到達
![Page 53: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/53.jpg)
MySQLのOFFSET処理のイメージ
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... .
id title user ... . id title user ... . id title user ... . id title user ... .
id title user ... .
1 2 3 4
5 6 7 8
9 10 11 12
13
10000
10001 10002 10003 10004
頑張ってソート
必要な個数まで到達
廃棄
![Page 54: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/54.jpg)
MOTTAINAI
![Page 55: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/55.jpg)
捨てるデータを減らす
![Page 56: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/56.jpg)
SELECT id FROM memos ORDER BY created_at LIMIT 100
OFFSET 10000
取得するデータを制限
![Page 57: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/57.jpg)
・・・・・
MySQLのOFFSET処理のイメージ
1 2 3 4 5 6 7 8 9 10 11 12 13
9999
id id id id id id id id id id id id id ・・・・・
id id
10000
id id id id
10001 10002 10003 10004
![Page 58: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/58.jpg)
・・・・・
MySQLのOFFSET処理のイメージ
1 2 3 4 5 6 7 8 9 10 11 12 13
9999
id id id id id id id id id id id id id ・・・・・
id id
10000
id id id id
10001 10002 10003 10004
廃棄読むデータも、捨てるデータも少ない
![Page 59: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/59.jpg)
“id” だけにすると高速になるもう一つの理由
“Covering Index”
![Page 60: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/60.jpg)
MySQLのインデックスとデータの持ち方
titleuser
....
titleuser
...
titleuser
...
titleuser
...
titleuser
...
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEYCLUSTERED INDEX
リーフノードにデータを含む
small largeid id id id id id id id
![Page 61: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/61.jpg)
MySQLのインデックスとデータの持ち方
SECONDARY KEYprimary keyじゃないkey
リーフノードにPRIMARY KEYが含まれ、データはCLUSTERED INDEX
から取得
id id id id id id id id
is_private
created_atolder newer older newer
![Page 62: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/62.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 63: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/63.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 64: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/64.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 65: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/65.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 66: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/66.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 67: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/67.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 68: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/68.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 69: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/69.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 70: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/70.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 71: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/71.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 72: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/72.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 73: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/73.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 74: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/74.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 75: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/75.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 76: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/76.jpg)
SELECT * の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
何度も繰り返す
![Page 77: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/77.jpg)
SELECT id の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 78: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/78.jpg)
SELECT id の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 79: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/79.jpg)
SELECT id の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 80: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/80.jpg)
SELECT id の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 81: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/81.jpg)
SELECT id の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 82: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/82.jpg)
SELECT id の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 83: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/83.jpg)
SELECT id の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 84: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/84.jpg)
SELECT id の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
![Page 85: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/85.jpg)
SELECT id の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
indexだけで探索が終わる
![Page 86: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/86.jpg)
SELECT id の場合
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
titleuser
....
PRIMARY KEY
id id id id id id id id
SECONDARY KEY
id id id id id id id id
is_private
created_at
= “Covering Index”indexだけで探索が終わる
![Page 87: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/87.jpg)
Covering Indexで高速に絞り込んだidの
titleなど、他のデータを取得する方法
![Page 88: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/88.jpg)
SELECT id FROM memos WHERE is_private = 0 ORDER BY created_at DESC, id DESC LIMIT 100 OFFSET 100000
クエリ1
(1) IN 句
SELECT * FROM memos WHERE id IN (10000,10001,10002,1003,....) ORDER BY created_at DESC, id DESC
クエリ2 ID羅列
![Page 89: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/89.jpg)
SELECT memos.id, memos.title, memos.is_private, memos.created_at, users.username FROM memos, users, (SELECT id FROM memos WHERE is_private = 0 ORDER BY created_at DESC, id DESC LIMIT 100) AS t WHERE t.id = memos.id AND users.id = memos.user
クエリ
(2) SELF JOIN
サブクエリーを使用し派生テーブル”t”を作成派生テーブル”t”と
元のテーブルをJOIN
![Page 90: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/90.jpg)
スコア
3060 => 4234よりクエリの少ないSELF JOINを使いました
![Page 91: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/91.jpg)
(9) その他インデックス
![Page 92: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/92.jpg)
cat <<'EOF' | mysql -u isucon isuconALTER TABLE memos ADD INDEX (is_private,created_at), ADD INDEX mypage(user,created_at), ADD INDEX memo_private(user,is_private,created_at)EOF
init.sh
![Page 93: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/93.jpg)
my $memos = $self->dbh->select_all( "SELECT id FROM memos WHERE user=? $cond ORDER BY created_at", $memo->{user},);
webapp/perl/lib/Isucon3/Web.pm
“/memo/xxx”
元は”*”だが、Covering Indexを狙って”id”に変更
![Page 94: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/94.jpg)
スコア
4234 => 5309
![Page 95: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/95.jpg)
(10) OFFSET殲滅データ構造を変更
![Page 96: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/96.jpg)
予めソート済みのmemoのリストがあり、BETWEEN句で
アクセスができればOFFSETで破棄される
データはいなくなり、エコ
![Page 97: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/97.jpg)
id memo1 42 63 8... ...... ...
10525 2127410526 2127710527 21280
... ...10626 2147710627 21480
... ...20627 41345
public_memosテーブル
OFFSET 10000の代わりにBETWEEN 10001 AND 10100
is_private=0 のmemoのidリストolder
newer
memoの個数にもなる!
![Page 98: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/98.jpg)
B-TreeでイメージPRIMARY KEY
older newerid id id id id id id id
memo
memo
memo
memo
memo
memo
memo
memo
BETWEEN 10001 AND 10100
![Page 99: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/99.jpg)
cat <<'EOF' | mysql -u isucon isuconDROP TABLE IF EXISTS public_memos;CREATE TABLE public_memos ( id INT NOT NULL AUTO_INCREMENT, memo int DEFAULT NULL, PRIMARY KEY (id)) ENGINE=MyISAM DEFAULT CHARSET=utf8;INSERT INTO public_memos (memo) SELECT id FROM memos WHERE is_private=0 ORDER BY created_at ASC, id ASC;EOF
init.sh
* innodb_autoinc_lock_mode の影響でInnoDBではauto increment が連続した値にならない可能性がある
![Page 100: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/100.jpg)
my $total = $self->dbh->select_one( 'SELECT MAX(id) FROM public_memos');my $memos = $self->dbh->select_all( 'SELECT memos.id, memos.title, memos.is_private, memos.created_at, users.username FROM memos,users, (SELECT memo FROM public_memos WHERE id BETWEEN ? AND ? ORDER BY id DESC) AS t WHERE t.memo = memos.id AND users.id=memos.user', $total-99, $total);
webapp/perl/lib/Isucon3/Web.pm
“/” or “/recent/xxx”
![Page 101: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/101.jpg)
my $memo_id = $self->dbh->last_insert_id;if ( ! scalar($c->req->param('is_private')) ) { $self->dbh->query('INSERT INTO public_memos (memo) VALUES (?)',$memo_id);}
webapp/perl/lib/Isucon3/Web.pm
post “/memo”
is_private = 0 ならpublic_memosにもinsert
![Page 102: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/102.jpg)
スコア
5309 => 8720
![Page 103: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/103.jpg)
あと、セッション周りのクエリを減らしたりすると
![Page 104: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/104.jpg)
スコア
8720 => 9079
![Page 105: ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版](https://reader033.vdocuments.net/reader033/viewer/2022052315/54b768844a7959a23c8b4851/html5/thumbnails/105.jpg)
Cache がなくても SQL やインデックスのチューニングでここまで変わる、この問題は面白いなぁと思いました。
出題の@fujiwaraさん、@acidlemonさんをはじめKAYACの皆様にあらためて感謝