搞懂 size / length / count 之間的差別
stackoverflow 上有這麼一段最佳留言
在每次遇到都很疑惑下,就實際測試並做個筆記
在必然觸發 query 的情境下,比較三者差別
1 | > User.all.length |
調用
length
select * from users
撈取所有的 user 數據- 最後返回數據筆數
調用
count
和size
- 一樣的 query 語句
select count(*) from users
- 都不是撈出所有數據,而是直接調用計算筆數的語句
count
- 效能顯而易見略勝
- 一樣的 query 語句
疑惑:那 count 跟 size 有什麼差別呢?
在確定不會觸發 query 的情境下,比較三者差別
1 | > user = User.find(72) |
size
和length
- 都因為先前 relations build 而返回 1 筆數據。
- 但兩者都沒有 query 的語句,等於是在該實例中直接計算筆數。
count
- 仍然 touch DB,有著一條 query 語句。
- 實例變量情境下
count
仍產生了一條 query 的效能。
總結
應該根據各種情境使用對應的方法
至於 length
就可以不用,因為 size
可以符合大部分的情境
不過瞭解後可以更精確的使用 count
像是確實要 DB 重新獲取真實數據的筆數,也就是 query 的效能已是不可避免
可以用兩種方式:
1 | > user.topics.reload.size |
又或者使用 count
1 | > user.topics.count |
當我們寫測試時 context "User will create and receive notifications"
預期得到一筆數據,假設預期數據不一樣,使用 reload 後,可以得到正確的數據
1 | expect(subject).to eql(user.topics.reload.size) |
可以避免寫 reload 寫法,看起來符合語意也很漂亮
1 | expect(subject).to eql(user.topics.count) |