2012-06-01 3 views
1

이름이 토큰 인 모든 레코드를 찾는 Rails ActiveRecord 쿼리가 있습니다.두 번째 시간을 질질 끌지 않고 Rails 레코드 수를 얻으십시오.

records = Market.where("lower(name) = ?", name.downcase); 
rec = records.first; 
count = records.count; 

서버는 .first.count에 대한 호출이 BOTH 데이터베이스를 타격 한 것으로 나타났다.

←[1m←[35mCACHE (0.0ms)←[0m SELECT "markets".* FROM "markets" WHERE (lower(nam 
e) = 'my market') LIMIT 1 

←[1m←[36mCACHE (0.0ms)←[0m ←[1mSELECT COUNT(*) FROM "markets" WHERE (lower(na 
me) = 'my market')←[0m 

이미 쿼리 한 결과를 사용할 수있을 때 카운트를 얻는 이유는 무엇입니까?

향후 성능에 대해 우려하고 있습니다. 오늘날에는 1000 개의 레코드가 있습니다. 이 테이블에 800 만 개의 행이 저장되고 데이터에 대해 두 개의 쿼리를 수행하고 개수에 대해 두 개의 쿼리를 수행하면 비용이 많이 듭니다.

데이터베이스가 아닌 컬렉션에서 카운트를 얻으려면 어떻게해야합니까?

답변

8

RactiveRecord는 데이터베이스에서 데이터를 가져 오기 위해 지연 쿼리를 사용합니다. 레코드를 간단하게 계산하려면 retrun 배열의 크기 만 호출하면됩니다.

records = Market.where("lower(name) = ?", name.downcase).all 
records.size 
+0

맞습니다. 더 많은 설명 -> http://rhnh.net/2007/09/26/counting-activerecord-associations-count-size-or-length –

+0

Rails 5 업데이트. records.count를 records.size로 변경하면 여전히 추가 db 쿼리. 하지만 그것을 레코드로 바꾸세요. 길이는 없었습니다. 그래서 레코드를 시도해보십시오. 길이. 또한 끝에 .all을 추가해도 쿼리 결과에는 아무런 차이가 없었습니다. –

+0

t.length는 DB 쿼리 (레일스 5 사용) – Kaz

6

그래서, recordsActiveRelation입니다. where 기준과 일치하는 모든 시장 기록의 배열이라고 생각할 수 있지만 그렇지 않습니다. 해당 관계에 first 또는 count과 같은 내용을 참조 할 때마다 요청한 내용을 검색하는 쿼리가 수행됩니다.

실제 레코드를 배열로 가져 오려면 .all을 실제로 관계를 검색하기 위해 추가하십시오. 좋아요 :

records = Market.where("lower(name) = ?", name.downcase).all 
count = records.count 
관련 문제