- 我目前有一張600,000,000行的表。
- 我想通過使用Group By子句對數據執行Daily Average來減少我的報告應用程序的行數。
然後將使用我的報告應用程序中較小的數據子集(減少99%)。查看或存儲過程的聚合查詢?
由於這將每天「建造」什麼是最好的工具 - 存儲過程,視圖或其他東西?
然後將使用我的報告應用程序中較小的數據子集(減少99%)。查看或存儲過程的聚合查詢?
由於這將每天「建造」什麼是最好的工具 - 存儲過程,視圖或其他東西?
構建和維護彙總表。最初,您需要運行一個大的GROUP BY
來收集所有的舊數據。之後,每晚的工作將計算前一天的COUNT(*)
,SUM(...)
等。
然後'報告'對這個新表格運行得更快。
該表的關鍵將包括日(不是日期+時間),以及您可能需要用於報告的幾列。
我發現典型的加速是10倍;你可能會獲得100倍(減少99%)。
最好的工具是你通過cron運行的腳本(或者MySQL EVENT
)。它可以簡單地做類似
INSERT INTO SummaryTable (dy, ..., ct, tot, ...)
SELECT DATE(datetime), ..., -- key
COUNT(*), SUM(..), ... -- data
FROM FactTable
WHERE datetime >= CURDATE() - INTERVAL 1 DAY
AND datetime < CURDATE();
這一個SQL語句可能是所有需要的。是的,它可能在一個存儲過程中,但這與直接在夜間腳本中沒有多大區別。
在某些情況下,使用INSERT ... ON DUPLICATE KEY UPDATE ... SELECT ...
可能會更好(但會變得混亂)。
在談到「平均數」,考慮以下因素:
AVG(...)
,但SUM(daily_sums)/SUM(daily_counts)
。也就是說,彙總表可能需要COUNT(*)
和SUM(...)
。要初始填充此彙總表,我會編寫一次性腳本,以便每天慢慢地遍歷600M行。當然,你可以一次完成所有的事情,但是對其他事情的干涉可能是「不好的」。
更好的辦法是每晚的腳本包含代碼以「拾取停止的位置」。這樣,如果腳本無法運行一晚,它會在第二天晚上修復該遺漏。或者您可以在發現問題時手動運行它。額外的跑步不會傷害任何東西。
當你在這裏,想想你可能需要的其他彙總表。我通常發現數據倉庫應用程序需要3-7個彙總表。另一方面,請記住每週和每月的摘要可以從每日摘要表中(足夠有效地)推導出來。在一些情況下,我有一個小時總結表,一個事情,然後每天表不同的事情。
600M行很大。將「舊」數據清除嗎?一旦你有了你需要的彙總表,不再需要「舊」數據了嗎? Blog on using Partitioning for such。
謝謝你輸入所有這些。這幫助我通過創建存儲過程來獲得我正在尋找的內容,存儲過程插入昨天的平均值,然後創建一個執行它的事件。 – OmisNomis
您將有一份工作可以執行查詢,將結果保存到表中並執行其他簿記操作。 –
視圖沒有實現或緩存,所以如果要生成新的聚合結果,將它們存儲在表中,然後查詢您將使用存儲過程提供的過程方法,則不會獲得使用它的性能優勢。 –
因此,建議使用存儲過程每天運行一項將新記錄插入到新表中的作業? – OmisNomis