2011-02-03 1 views
2

Foo 형식의 모델에 Bar 형식의 자식 레코드가 많이있는 경우 Foo 레코드 목록을 표시하고 자식 막대 수를 표시하고 싶습니다. 기록. 그래서 DataMapper 집계를 사용하여 N + 1을 피하는 방법

@foos.each do |foo| 
    puts foo.name 
    puts foo.bars.count 
end 

가 어떻게 내 집계에 N+1 problem를 방지 할 수 있습니다 ... 뭔가 같은이? 즉, 각 행에 대해 새로운 SELECT COUNT(*)... 쿼리를 원하지 않습니다. 간단히 SQL보기를 작성하여 새 모델에 맵핑 할 수 있지만 더 간단한 접근 방법이 있습니까?

답변

1

DataMpper는 이러한 것들에 대해 변덕스러워하므로 실제 코드가 어떻게 생겼는지에 따라 작동 할 수있는 몇 가지 옵션을 제공 할 것입니다.

  1. 단지 count를 size로 변경합니다. 즉, foo.bars.size를 넣습니다. DM의 전략적 열렬한 로딩은이 접근법과 함께 작동 할 수 있습니다.

  2. 포스에서 @ foos.each 루프 전에 열망 부하 변화 크기, 예컨대로 계산

    @foos = Foo.all(...) 
    @foos.bars.to_a 
    @foos.each do | foo | 
        puts foo.name 
        puts foo.bars.size 
    end 
    
  3. 문제 foo는 ID와 바 건의 구조체를 반환은 @ foos.each 루프 전에 원시 SQL 쿼리, 식품 ID로 해시로 사람들을 #map 루프 내부에 그들을 얻을. (나는 한 번 또는 두 번이 레벨의 넌센스에 의지해야만했다. # 1과 2를 사용하기 전에 비트를 사용하는 것이 좋습니다.)