GitLabのスロークエリを駆逐するマージリクエストを送りました
GitLabにマージリクエストを送ってみました。
以前の経験からGitLabの開発チームはGitHubはほぼ見てないことを知っていたのでGitLabから送ってみました。
ちなみに上のエントリに出てくるGritが使われている箇所は現在ではすべてRuggedに書き換わっているので状況は変わっています。
マージリクエスト送った! / “'created_at DESC' is performed twice (#825) | Merge Requests | http://t.co/LLbgkxK7A7 / GitLab Comm…” http://t.co/F91TCk67US
— 健康診断@4/26 (@catatsuy) 2015年6月16日
GitLabの人たちはGitHub見てないのでちゃんとGitLabから送った
— 健康診断@4/26 (@catatsuy) 2015年6月16日
GitLabはGitHubでログインする機能があって愉快な感じでした(SSHの鍵をインポートする機能は現時点ではないようです)。
GitLabはGitHubでログインする機能があって愉快
— 健康診断@4/26 (@catatsuy) 2015年6月16日
肝心の内容ですが、なんか社内のGitLabが遅くなってきたのでいろいろ調査をしていたところMySQLに遅いクエリがあることに気付きました。
そのクエリは以下の様な感じになっていました。
SELECT `events`. * FROM `events` WHERE ( `events`.`author_id` IS NOT NULL ) AND `events`.`project_id` IN ( 10 ,9 ,8 ) ORDER BY `events`.`created_at` DESC ,`events`.`id` DESC ,created_at DESC LIMIT 20 OFFSET 0 ;
よく見るとcreated_at DESC
が2つあるし、RailsのActiveRecordの規則から逸脱しているので何か不穏な感じがします。本来なら以下のようになって欲しいです。
SELECT `events`. * FROM `events` WHERE ( `events`.`author_id` IS NOT NULL ) AND `events`.`project_id` IN ( 10 ,9 ,8 ) ORDER BY `events`.`created_at` DESC ,`events`.`id` DESC LIMIT 20 OFFSET 0 ;
ということで調べると不穏な感じのメソッドがありました。
created_at DESC
を直接文字列で渡しているのでRailsが既に付けている場合でも判断できずに2重に付けてしまいます。Railsの機能で付ければ2重に呼び出しても2重に付けることはないのでちゃんとRailsの機能を使ってあげます。
2重についても問題ないならいいのですが、MySQLの場合だとSQLの実行計画がおかしくなって全行を見るようになってしまいます。1つだけなら早いクエリです。
早くマージされるといいなー
このMRを取り込むと謎のスロークエリが駆逐されるのでみんな応援して欲しい
— 健康診断@4/26 (@catatsuy) 2015年6月16日
@catatsuy BeforeだけじゃなくてAfterも書くとよいのでは!? e.g. https://t.co/Af8jBCDxS5
— Ryuta Kamizono (@kamipo) 2015年6月16日
@catatsuy good job!
— Ryuta Kamizono (@kamipo) 2015年6月16日