2012-11-02 80 views
1

我有一個模型 - Link - 有很多命中。我正在嘗試的是從數據庫表中隨時間推移每小時的點擊數的彙總數據 - hits - 列yearmonth,dayhourRails在查詢結果

一切工作正常,但是當我運行下面的代碼時,最後幾乎1,000數據庫上的查詢,這似乎是非常過分。

#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 

這裏tTime對象,在1小時的步驟迭代由於第一打一個鏈路接收。

我會認爲,軌會存儲查詢結果,而不是每次重新查詢。我也無法找到關於緩存查詢結果或任何內容的任何信息。我只是完全錯過了一些東西,還是這真的是最簡單的方法?

這裏的查詢是什麼樣子的樣本(這是我在日誌中看到一千年的塊):

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個查詢請求什麼?這可以通過急切加載協會來改善嗎? – pje

+0

沒有關聯正在加載。自創建鏈接以來,它每小時運行一次(現在大約3周)。我將爲該問題添加一個查詢示例。 – Jon

回答

3

確定。所以@hits將成爲ActiveRecord :: Relation對象 - 本質上是一個SQL查詢。我相信因爲每次迭代都會調用.where以及不同的參數,從而改變查詢,Rails決定每個小時都要重新運行查詢。

的簡單的解決辦法可能是「崩潰」關係到一個數組迭代前,然後用純Ruby來選擇的結果,你希望每個時間:

@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

@Jon謝謝。我自己會嘗試'更好'的解決方案,但我清楚地記得,分組是mysql最不像Postgres(我的數據庫專長所在)的地方之一。 – MrTheWalrus

+0

我的答案是一樣的。如果有更好的解決方案,則取決於您希望進行這些查詢的次數。我的意思是,緩存如何獲得更多的點擊? –