読者です 読者をやめる 読者になる 読者になる

GitLabのスロークエリを駆逐するマージリクエストを送りました

GitLabにマージリクエストを送ってみました。

gitlab.com

以前の経験からGitLabの開発チームはGitHubはほぼ見てないことを知っていたのでGitLabから送ってみました。

catatsuy.hateblo.jp

ちなみに上のエントリに出てくるGritが使われている箇所は現在ではすべてRuggedに書き換わっているので状況は変わっています。

GitLabはGitHubでログインする機能があって愉快な感じでした(SSHの鍵をインポートする機能は現時点ではないようです)。

肝心の内容ですが、なんか社内の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つあるし、RailsActiveRecordの規則から逸脱しているので何か不穏な感じがします。本来なら以下のようになって欲しいです。

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
;

ということで調べると不穏な感じのメソッドがありました。

http://i.gyazo.com/28b6e8b0d8eae203aa6e8840b3fd785a.png

created_at DESCを直接文字列で渡しているのでRailsが既に付けている場合でも判断できずに2重に付けてしまいます。Railsの機能で付ければ2重に呼び出しても2重に付けることはないのでちゃんとRailsの機能を使ってあげます。

2重についても問題ないならいいのですが、MySQLの場合だとSQLの実行計画がおかしくなって全行を見るようになってしまいます。1つだけなら早いクエリです。

早くマージされるといいなー