2013-07-27 44 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?