2013-07-27 40 views
1

我正在構建一個網站分析工具並使用Postgresql作爲數據庫。我不會插入Postgres的每個用戶的訪問,但只有彙總數據分別5秒期間:帶有postgres的網站分析架構

time country browser num_visits 
======================================== 
0  USA  Chrome  12 
0  USA  IE   7 
5  France  IE   5 

正如你可以看到每5秒一個我插入多行(每個維度組合中的一個)。

爲了減少查詢中需要掃描的行數,我想根據分辨率使用上述模式的多個表:5SecondResolution,30SecondResolution,5MinResolution,...,1HourResolution。現在,當用戶詢問最後一天時,我將轉到小於5秒分辨率表格的小時分辨率表格(儘管我也可以使用那個表格 - 這只是更多行掃描)。

現在如果小時分辨率表具有小時0,1,2,3,...的數據,但用戶要求從小時的1:59到8:59看到小時的趨勢。爲了獲得1:59-2:59的數據,我可以對不同的分辨率表進行多種查詢,所以我從1分辨率獲得1:59:2:00,從30分辨率獲得2:00-2:30等等。 AFAIU我已經把一個查詢交易到一個巨大的表(有許多相關的行要掃描),多個查詢到中表+在客戶端結合結果。

這聽起來像是一個很好的優化? 對此有何其他考慮?

+0

目前尚不清楚首先要解決的問題。什麼推動你需要優化這個?順便說一句,這聽起來像是一個很好的用於PostgreSQL 9.4的minmax索引的用例。這是一段時間了,但最初的結果在大餐桌上很不錯。 –

+0

問題是,如果我只使用一個表格(5秒分辨率,因爲它是我需要的最高分辨率),那麼在幾天時間內實際上對小時分辨率感興趣的查詢將需要做一個完整的表格掃描(可能有500M行)。我想通過使用具有相同數據但分辨率較低(5分鐘,1小時等)的附加表格來緩解它的想法。 –

回答

1

現在如果小時分辨率表具有小時0,1,2,3,...的數據,但用戶會要求查看小時從1點59分到8點59分的趨勢。爲了獲得1:59-2:59的數據,我可以對不同的分辨率表進行多種查詢,所以我從1分辨率獲得1:59:2:00,從30分辨率獲得2:00-2:30等等。

如果你希望你的結果準確,你不能這麼做。想象一下,如果他們要求在01:30到04:30之間解決一小時的問題。你在想象你會從5秒(或1分鐘)的資源表中獲得第一個和最後一個半小時,然後從一個小時的表中獲得其餘的時間。

問題是,一小時表偏移了半個小時,所以答案實際上並不正確;當用戶想要2:30到3:30時,每個小時將從2:00到3:00等。當您選擇更粗略的解決方案時,這是一個更嚴重的問題。

因此:這是一個完全合理的優化技術,但前提是您將用戶的搜索開始精度限制爲聚合表的分辨率。如果他們想要一個小時的解決方案,強迫他們選擇1:002:00等,並禁止設置分鐘。如果他們想要5分鐘的分辨率,讓他們選擇1:00,1:05,1:10 ......等等。您不必以同樣的方式限制結束精度,因爲不完整的結束間隔不會影響結束之前的數據,並且在顯示時很容易被標記爲不完整。 「當前日期」,「迄今爲止的小時」等。

如果限制起始精度,不僅可以給它們正確的結果,還可以大大簡化查詢。如果限制年底精度也然後將查詢純粹是對彙總表,但如果你想「最新」的數據是很容易寫的東西,如:

SELECT blah, mytimestamp 
FROM mydata_1hour 
WHERE mytimestamp BETWEEN current_date + INTERVAL '1' HOUR AND current_date + INTERVAL '4' HOUR 
UNION ALL 
SELECT sum(blah), current_date + INTERVAL '5' HOUR 
FROM mydata_5second 
WHERE mytimestamp BETWEEN current_date + INTERVAL '4' HOUR AND current_date + INTERVAL '5' HOUR; 

...甚至使用幾個以滿足對更粗略決議的要求。

+0

如果他們從1:30到4:30問我不會使用每小時分辨率表,但每半小時表(或甚至每分鐘表)。僅比5秒的分辨率更有效。 –

1

您可以使用繼承/分區。一個分辨率的主表和許多小時分辨率的兒童表格(也許還有許多分鐘和秒鐘的分辨率兒童表格)。

因此,您只需從主表中選擇,讓每個子表的約束決定哪個是哪個。

當然,你必須添加一個觸發器函數來將insert分離到合適的子表中。

插入的複雜性與顯示的複雜性。

PostgreSQL - View or Partitioning?