はじめに
ActiveRecordのpluckとRubyのmapをどう使い分けるのかを調べた内容をまとめます。
結論
- 一回の処理を行う場合はpluckを利用する方が良い=メモリの使用量が少ない
- ループ処理を行う場合はmapを利用する方が良い=SQLの発行は一回のみなのでパフォーマンスが低下しない
pluck
- ActiveRecordのメソッド
Journal.pluck(:id)
# SQL
SELECT `journals`.`id` FROM `journals`
-
SELECT journals.id
= 特定のカラムのデータをDBから直接取得する - ActiveRecordオブジェクトのインスタンス化は行わないため、メモリ使用量が少ない
Array#mapで書き換える場合
Journal.all.map(&:id)
# SQL
SELECT `journals`.* FROM `journals`
-
SELECT journals.*
= 全てのカラムのデータを取得し、取得したデータから特定のカラムのデータを取得する
ループ処理の場合
- pluckはループ処理で毎回SQLを発行するためパフォーマンスが低下する
- mapはSQLの発行は一回のみ
journals = Journal.all
n = 100
Benchmark.bm do |x|
x.report{n.times {journals.pluck(:id)}}
x.report{n.times {journals.map(&:id)}}
end
user system total real
(1.4ms) SELECT `journals`.`id` FROM `journals`
(1.0ms) SELECT `journals`.`id` FROM `journals`
(0.8ms) SELECT `journals`.`id` FROM `journals`
(0.9ms) SELECT `journals`.`id` FROM `journals`
(0.8ms) SELECT `journals`.`id` FROM `journals`
(1.0ms) SELECT `journals`.`id` FROM `journals`
(0.7ms) SELECT `journals`.`id` FROM `journals`
(0.7ms) SELECT `journals`.`id` FROM `journals`
(0.9ms) SELECT `journals`.`id` FROM `journals`
(1.1ms) SELECT `journals`.`id` FROM `journals`
(1.0ms) SELECT `journals`.`id` FROM `journals`
(0.8ms) SELECT `journals`.`id` FROM `journals`
(0.8ms) SELECT `journals`.`id` FROM `journals`
(1.1ms) SELECT `journals`.`id` FROM `journals`
# 省略 # SQLを100回発行
0.098621 0.028786 0.127407 ( 0.164498)
Journal Load (1.1ms) SELECT `journals`.* FROM `journals`
0.005030 0.001110 0.006140 ( 0.006611)
参考