답변:
당신은 읽어야 것을 여전히 유효입니다.
필요에 따라 사용하는 기능을 조정합니다.
원래:
이미 모든 항목을로드하는 경우 (예 User.all
: length
다른 DB 쿼리를 피하기 위해 사용해야 함)
아무것도로드하지 않은 경우을 사용 count
하여 DB에서 개수 쿼리를하십시오.
이러한 고려 사항에 신경 쓰지 않으려면 사용할 size
것을 사용하십시오.
size
전화를 걸 때 size
( 전화 할 전화를 결정한 후) 전화를 걸 수 있습니다.
Comment.create(post_id: post.id)
당신, post.comments.size
동안 의지는 최신이 아닐 post.comments.count
것입니다. 그러니 조심하세요
company.devices.build(:name => "device1"); company.devices.build(:name => "device2")
다음 company.devices.size
과 .length
당신이 구축했지만 저장하지 않은 개체의 수를 포함 .count
데이터베이스에서 단지 수를보고합니다.
다른 답변은 다음과 같이 말합니다.
count
SQL COUNT
쿼리 를 수행 합니다length
결과 배열의 길이를 계산합니다size
과도한 쿼리를 피하기 위해 둘 중 가장 적절한 것을 선택하려고합니다.그러나 한 가지 더 있습니다. 우리는 완전히 / size
다르게 행동 하는 경우를 발견했으며 간과하기가 드물기 때문에 그것을 공유 할 것이라고 생각했습니다.count
length
당신은을 사용하는 경우 :counter_cache
A의 has_many
연결, size
직접 계산 캐시 된을 사용하고, 전혀 추가 질의를하지 않습니다.
class Image < ActiveRecord::Base
belongs_to :product, counter_cache: true
end
class Product < ActiveRecord::Base
has_many :images
end
> product = Product.first # query, load product into memory
> product.images.size # no query, reads the :images_count column
> product.images.count # query, SQL COUNT
> product.images.length # query, loads images into memory
이 동작은 Rails Guides 에 설명되어 있지만 처음 놓쳤거나 잊어 버렸습니다.
_count
열 이 있어도 ( counter_cache: true
연결에 대한 지시어가 없는 경우)이 동작이 트리거됩니다 . 이것은 github.com/rails/rails/commit/e0cb21f5f7
count
.length
.size
...Select count(*)...
쿼리를 DB 로 전송합니다 . 데이터가 필요하지 않고 카운트 만 있으면 갈 수 있습니다.
예 : 새 메시지 수, 페이지 만 표시 될 때의 총 요소 수 등
필요한 데이터, 즉 필요에 따라 쿼리를로드 한 다음 계산합니다. 데이터를 사용하는 경우 갈 길.
예 : 완전히로드 된 테이블 요약, 표시된 데이터 제목 등
데이터가로드되었는지 (즉, 이미 레일에)로드되어 있는지 확인한 다음 카운트 만하고 그렇지 않으면 count를 호출합니다. (다른 항목에서 이미 언급 한 함정).
def size
loaded? ? @records.length : count(:all)
end
뭐가 문제 야?
올바른 순서로 수행하지 않으면 DB를 두 번 누르게 될 수 있습니다 (예 : 렌더링 된 테이블 위에 테이블의 요소 수를 렌더링하는 경우 실제로 DB에 2 개의 호출이 전송 됨).
다음 전략은 모두 데이터베이스를 호출하여 COUNT(*)
쿼리 를 수행 합니다.
Model.count
Model.all.size
records = Model.all
records.count
다음은 데이터베이스의 모든 레코드를 Ruby로로드하는 것만 큼 효율적이지 않으며, 컬렉션의 크기를 계산합니다.
records = Model.all
records.size
모델에 연결이 있고 소속 개체 수 (예 :)를 찾으려면 @customer.orders.size
데이터베이스 쿼리 (디스크 읽기)를 피할 수 있습니다. 카운터 캐시를 사용하면 Rails는 캐시 값을 최신 상태로 유지하고 size
메소드 에 대한 응답으로 해당 값을 반환합니다 .
Model.all.size
와 Model.all.count
생성 count
레일 4 위의 쿼리를. 실제 장점은 size
연결이 이미로드 된 경우 개수 쿼리를 생성하지 않는다는 것입니다. Rails 3 이하에서는 Model.all
관계가 없다고 생각 하므로 모든 레코드가 이미로드되었습니다. 이 답변이 오래되었을 수 있으므로 삭제하는 것이 좋습니다.
크기 기능을 사용하는 것이 좋습니다.
class Customer < ActiveRecord::Base
has_many :customer_activities
end
class CustomerActivity < ActiveRecord::Base
belongs_to :customer, counter_cache: true
end
이 두 모델을 고려하십시오. 고객에게 많은 고객 활동이 있습니다.
has_many 연관에서 : counter_cache를 사용하면 size는 캐시 된 수를 직접 사용하고 추가 쿼리를 전혀하지 않습니다.
한 가지 예를 생각해보십시오. 데이터베이스에서 한 고객은 20,000 개의 고객 활동을 가지고 있으며 각 고객 수, 길이 및 크기 방법으로 해당 고객의 고객 활동 레코드 수를 세려고합니다. 이 모든 방법의 벤치 마크 보고서 아래에 있습니다.
user system total real
Count: 0.000000 0.000000 0.000000 ( 0.006105)
Size: 0.010000 0.000000 0.010000 ( 0.003797)
Length: 0.030000 0.000000 0.030000 ( 0.026481)
그래서 : counter_cache Size를 사용하는 것이 레코드 수를 계산하는 가장 좋은 옵션이라는 것을 알았습니다.
size
어쨌든 상황에 적응하고 무엇을 필요로하기 위해 존재length
와count
전혀?