【Rails】データの件数を取得する方法!count, length, sizeの違いとは?

データの件数を取得したいんだけど何を使ったらいいの?

件数を取得するメソッドはいくつかあるんだけど、
それぞれ特徴があるから解説していくね!

目次

データの件数を取得するメソッド

データの件数を取得するためにはMVCのモデルに相当するActive Recordのメソッドを使ってデータベースからデータの件数を取得します。

件数の取得にはcountメソッド、lengthメソッド、sizeメソッドの3種類あります。

users = User.all # 10件レコードがあるとき

users.count # => 10
users.length # => 10
users.size # => 10

取得結果としてはいずれも同じですが、件数を数える処理に違いがあります。

それは実行した結果をキャッシュ(メモリに保存)するかの違いです。

キャッシュの動作

count → キャッシュしない

length → キャッシュする

size → キャッシュする

この特徴を使い分けることで件数を取得する際のパフォーマンスや最新のデータの取得状況が変わってくるので、
状況に応じてこれらのメソッドを使い分けていきます。

これらのメソッドについてさらに詳しく解説していきます。

countメソッド

countメソッドは実行する度に毎回データベースに対してクエリ(SQL)を発行します。

毎回クエリを発行するので件数はキャッシュされておらず、毎回新たな件数を取得してきます。

> users = User.all # usersテーブルのレコードを全件取得

> users.count # レコードの件数を取得
SELECT COUNT(*) FROM `users`
=> 10

> users.count # 再度レコードの件数を取得
SELECT COUNT(*) FROM `users`
=> 10

このようにcountメソッドを実行するたびにクエリが発行されていることが分かります。

そのためcountメソッドは最新の件数を取得することが可能です。

しかし、eachなどの繰り返し処理でcountメソッドを使ってしまうと毎回データベースにアクセスして件数を取得してしまうため、パフォーマンスが下がってしまうので注意しましょう。

  • 実行する度に毎回クエリ(SQL)を発行する
  • 最新の件数を取得できる
  • パフォーマンス面で注意が必要

lengthメソッド

lengthメソッドは実行すると結果をメモリに保存します。

データがキャッシュされているため毎回クエリを発行する必要がありません。

> users = User.all # usersテーブルのレコードを全件取得

> users.length # レコードの件数を取得
SELECT COUNT(*) FROM `users`
=> 10

> users.length # 再度レコードの件数を取得
=> 10

2回目以降はキャッシュされたデータの件数が参照されるので、lengthメソッドを実行してもクエリは発行されません。

しかし、何度lengthメソッドを実行したとしてもキャッシュしたデータを参照するため、最新の件数は取得されないことに注意しましょう。

  • 初回の実行結果がメモリに保存される
  • キャッシュされたデータを参照するので最新の件数を取得できない
  • 最新のデータを利用しないのであればパフォーマンスが良い

sizeメソッド

sizeメソッドはメモリにデータがあればそれを参照し、なければクエリを発行し続けて最新のデータを取得します。

countメソッドとlengthメソッドの両機能を合わせ持ったメソッドになります。

件数取得時にデータがキャッシュされていない状態であればcountメソッドと同じような動作をし、件数を取得する度にクエリを発行します。

> users = User.all # usersテーブルのレコードを全件取得

> users.size # レコードの件数を取得
SELECT COUNT(*) FROM `users`
=> 10

> users.size # 再度レコードの件数を取得
SELECT COUNT(*) FROM `users`
=> 10

また、逆にデータがキャッシュされている状態であればlengthメソッドと同じような動作をし、キャッシュしたデータが参照されます。

> users = User.all # usersテーブルのレコードを全件取得

> users.length # レコードの件数を取得
SELECT COUNT(*) FROM `users`
=> 10

> users.size # 再度レコードの件数を取得
=> 10

キャッシュの状態でクエリを発行するかしないか決まるのが特徴です。

  • 取得件数をキャッシュしていないときはcountメソッドと同じ動作をする
  • 取得件数をキャッシュしているときはlengthメソッドと同じ動作をする
  • キャッシュの状況に注意しながら利用する必要がある

どのメソッドを使うべきなのか

件数を取得するという点であればどのメソッドを使っても構いません。

しかし、パフォーマンスを高めたいときやデータの鮮度を高く保ちたいときなどは、その状況によって使い分けてみてください。

どのような状況で使うと最適なのかまとめておきます。

count」メソッドをおすすめするとき
  • 最新のデータを取得したいとき
  • eachなどの繰り返し処理で使う必要がないとき(1回のみ件数を取得したいとき)
length」メソッドをおすすめするとき
  • 最新のデータが不要なとき(キャッシュした1回目のデータの鮮度で十分なとき)
  • eachなどの繰り返し処理で使うとき
size」メソッドをおすすめするとき
  • キャッシュの状況によって使い分けたいとき

sizeメソッドはキャッシュの状況によって発行されるクエリが変わるので注意しましょう。

まとめ

件数を取得するメソッドについて解説したよ!

  • countメソッドは毎回クエリを発行して件数を取得する(件数をキャッシュしない)
  • lengthメソッドは2回目以降はキャッシュした件数を参照する
  • sizeメソッドはキャッシュの状況に応じでcountメソッドやlengthメソッドの動作をする

同じ件数を取得するメソッドでも違いがあるんだね!
使い分けながら使ってみる!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次