14. SQLの解析
• mysqlslowdumpコマンドで解析
$ mysqldumpslow [option] [log_file]
## よく使うオプションは-s(並び替え)
-s c → 総クエリ数の多い順
-s l → 総ロックタイムの長い順
-s r → 総行数の多い順
-s t → 総実行時間の長い順
-s a(l ¦ r ¦ c) → 各平均の長い順
15. ## 文字列 → S、 数字 → N と置換してくれる
## Count:総クエリ数 Time=平均実行時間(総実行時間)
## Lock=平均ロックタイム(総ロックタイム) Rows=平均行数(総行数)
$ mysqldumpslow -s c slow_query.log ¦ less
Count: 49 Time=1.49s (73s) Lock=0.00s (0s) Rows=1.0 (49),
user[user]@2hosts
SELECT * FROM tbl1 WHERE name = 'S' ORDER BY id LIMIT N
Count: 36 Time=1.47s (52s) Lock=0.00s (0s) Rows=1.0 (36),
user[user]@2hosts
SELECT * FROM tbl2 WHERE id = 'S' AND deleted = 'S' ORDER BY id LIMIT N
.
.
.
16. 重たいSQLの傾向
• 複数テーブルをまたいだORDER BY
SELCT *
FROM tbl1
INNER JOIN tbl2 ON ...
INNER JOIN tbl3 ON ...
ORDER BY tbl1.created DESC, tbl2.created.DESC
LIMIT 0, 20;
• ページングでよく使われるSQL
• Using temporary; Using filesort がどうして
も発生してしまう
17. 重たいSQL対応その1
• SQLを分割する(ID取得)
SELCT tbl1.id
FROM tbl1
INNER JOIN tbl2 ON ...
INNER JOIN tbl3 On ...
ORDER BY tbl1.created DESC, tbl2.created DESC
LIMIT 0, 20;
• レコードをIDのみにする
• レコードを減らすだけでもクエリ実行時間は
結構減る
18. 重たいSQL対応その1
• SQLを分割する(表示データ取得)
SELCT *
FROM tbl1
INNER JOIN tbl2 ON ...
INNER JOIN tbl3 On ...
WHERE tbl1.id = 1
• 取得したID毎に表示用のSQLを実行する
• SQL本数は増えるが、IDをキーに取得してい
るので実行時間は0.1secとかで収まる
19. 重たいSQL対応その2
• 無駄なJOIN、ORDER BYを減らす
SELCT tbl1.id
FROM tbl1
INNER JOIN tbl2 ON ...
// INNER JOIN tbl3を削除
ORDER BY tbl1.created DESC
LIMIT 0, 20;
• JOIN先のテーブルの件数次第では、JOINを減
らすだけでXsec下げれたりする
• ORDER BYも同様
• ある程度の不整合に目をつぶるかも。。