webエンジニアの日常

RubyやPython, JSなど、IT関連の記事を書いています

レコード数が多いテーブルの一覧はselectしておこう

こんにちは、さもです

タイトルの通りですが、レコード数が多いテーブルを一覧表示するような場合、しかも一部のカラムしか使わないときは、allではなく、selectを使った方が速かったです。例外もありました。

今、名前、メールアドレス、id、登録日時、更新日時、削除日時を持つEmailモデルに16000件レコードが入っているとします。

このとき、Email.allEmail.select(:name, :email)のSQLの速度を計ってみたいと思います。

結果は以下のようになりました。

スポンサーリンク

Email.all ・・・平均26.2ms

Email.select(:name, :email)・・・平均17ms

結果、selectした方が速いという結果になりました。

ちなみに、

Email.select(:name) ・・・平均12.3秒

Email.select(:name, :email, :created_at) ・・・ 平均21.5ms

のように使うカラムが少なければ速くなります。

しかし、

Email.select(:email).order(:created_at) ・・・ 平均49ms

Email.order(:created_at) ・・・平均40ms

なぜかorderをつけると逆転!

インデックスとかの問題でしょうか。必ずselectでカラムを絞ると速くなるというわけでもないようです。

Email.select(:created_at).order(:created_at)なら平均19msぐらいで速いのですが、、

SQLはあまり詳しくないので、結局原因は分かりませんでした。

実装する前にconsoleで試してみて速い方を採用する。という感じで行きます。

最後に、

Email.order(:created_at)Email.where(id: Email.select(:id).order(:created_at))だと、後者の方が平均5msほど速かったです。

並べ替えたidで検索する感じですね。

読者登録はこちらからお願いします。

スッキリわかる SQL 入門 ドリル215問付き! (スッキリシリーズ)

スッキリわかる SQL 入門 ドリル215問付き! (スッキリシリーズ)

SQLアンチパターン

SQLアンチパターン