count、size、lengthの違い(再考)

Railsハイパー実践講座 - 第35回NaCl勉強会 - - I am Cruby!
を読んでいて


count, size, length について
「DBからロード済であれば配列の件数、なければDBから実際にロードする」
と記載があった。

あれ

count、size、lengthの違い - うんたらかんたらRuby - Rubyist
で書いたように
lengthって、毎回リロードすると思っていた。


そうかロード時と、未ロード時で挙動が違うのか。

一応検証してみた

mysqlでクエリログを掃くように設定し

[mysqld]
#5.1以降はgeneral_logらしい
log=mysqld.log


親子関係のテーブルを用意して確認してみたところ
上記スライドのようになった。

要は

こんなかんじ。

方法ロード済の場合未ロードの場合備考
sizeコレクションの個数SELECT countカウンタキャッシュなど
countSELECT countSELECT count毎回カウント、条件設定可
lengthコレクションの個数SELECT *
(ロードする)
ロードして何かしたい場合

2012/11/24 追記

Count returns 0 without querying if parent is not saved by frodsan · Pull Request #6978 · rails/rails

length with always load the objects and use Array#length
count will always do a SQL count
size will check whether the collection is loaded, and use it, otherwise will do a count.