2012-11-02 2 views
1

나는 많은 모델이 Link - 그 안타가 많습니다. 내가 뭘 하려는지 데이터베이스 테이블에서 hits - year, month, dayhour 열 시간에 시간당 히트 데이터를 집계하는 것입니다.레일 어디 쿼리 결과에

모든 것이 정상적으로 작동하지만 아래 코드를 실행하면 데이터베이스에서 거의 개의 쿼리로 끝나기 때문에 상당히 과도한 것으로 보입니다.

#before iteration 
@hits = @link.hits.group('year, month, day, hour') 
    .order('year ASC, month ASC, day ASC, hour ASC') 
    .select('year, month, day, hour, count(*) as hits') 


#inside iteration 

#Line breaks are included here for easy reading 
hits_per_hour = 
    @hits.where(
    :year => t.year, 
    :month => t.month, 
    :day => t.day, 
    :hour => t.hour 
).map(&:hits).first || 0 

여기 t 1 시간 씩 반복 (Iteration)이 첫 수신 링크 충돌 이후 Time 목적이다.

난 레일이 매번 다시 쿼리하는 대신 쿼리 결과를 저장할 것이라고 생각합니다. 나는 또한 쿼리 결과 또는 아무것도 캐싱에 대해 아무것도 찾을 수 없었습니다. 내가 뭔가를 완전히 놓친 건가요? 아니면이게 가장 쉬운 방법입니까? 여기

(이 나는 천의 블록 내 로그에 표시되는 내용입니다) 쿼리 모양을 샘플입니다 : 좋아

SELECT year, month, day, hour, count(*) as hits 
FROM `hits` 
WHERE 
    `hits`.`link_id` = 1 AND 
    `hits`.`year` = 2012 AND 
    `hits`.`month` = 11 AND 
    `hits`.`day` = 2 AND 
    `hits`.`hour` = 14 
GROUP BY year, month, day, hour 
ORDER BY year ASC, month ASC, day ASC, hour ASC 
+0

질문하는 1000 개의 검색어는 무엇입니까? eager-loading associations에 의해 향상 될 수 있습니까? – pje

+0

로드 된 연관이 없습니다. 링크가 생성 된 후 매 시간마다 실행됩니다 (현재 약 3 주). 질문 중 하나의 샘플을 질문에 추가하겠습니다. – Jon

답변

3

. 따라서 @hits은 본질적으로 SQL 쿼리 인 ActiveRecord :: Relation 객체가 될 것입니다. 각 반복마다 .where에 다른 매개 변수가 호출되어 쿼리가 변경되므로 Rails는 매 시간마다 쿼리를 다시 실행해야한다고 결정했습니다.

간단한 수정은 할 때마다 원하는 결과를 선택하는 순수 루비를 사용하여 '붕괴'를 반복하기 전에 배열에 관계에 아마, 그리고 : 다음

@hits = @link.hits.group('year, month, day, hour') 
    .order('year ASC, month ASC, day ASC, hour ASC') 
    .select('year, month, day, hour, count(*) as hits').all 

과 :

hits_per_hour = (@hits.select{|record| record.year == t.year && record.month == t.month && record.day == t.day && record.hour == t.hour}.map(&:hits).first || 0) 

실제로이 방법이 최상의 솔루션이라고 생각하지 않습니다. 필요한 데이터와 수행중인 작업에 따라 데이터베이스에서 모든 작업을 수행 할 수 있어야합니다.

+0

나는 뭔가를 놓친다는 것을 알았다. 고맙습니다. 당신이 말했듯이, 이것이 최선의 해결책이 아닐 수도 있습니다. 그래서 나는 대답을 받아 들일 때까지 기다릴 것입니다. 하루가 끝날 무렵에 더 좋은 것이 없다면 당신은 분명히 그것을 얻고 있습니다. – Jon

+0

@ 존 고마워. 나는 '더 나은'해결책을 직접 취할 것이지만, 그룹핑은 mysql이 최소한 포스트그레스 (내 데이터베이스 전문 지식이있는 곳)와 같은 곳이라는 것을 명심해야한다. – MrTheWalrus

+0

내 대답은 같을 것이다. 그리고 더 좋은 해결책이 있다면 그것은 얼마나 많은 시간을 당신이 그 쿼리를 할 것으로 예상하는지에 달려 있습니다. 캐쉬가 어떻게 더 많은 히트를 얻을 수 있을까요? –