0

我有一个系统可以保存网络中服务器的统计信息。稍后,用户可以使用所有数据并计划其增长。因此,将数据汇总成图表非常重要,即跨越一个小时、一天、一周、一年等。

我正在尝试做这样的事情:

select created_time / 60, count(*)
from pm_server_stat
group by (created_time / 60);

--with this index
CREATE INDEX pm_server_stat_created_time_60
  ON pm_server_stat
  USING btree
  ((created_time / 60));

这是我得到的解释

"GroupAggregate  (cost=189822.36..213951.06 rows=1206435 width=8)"
"  Output: ((created_time / 60)), count(*)"
"  ->  Sort  (cost=189822.36..192838.45 rows=1206435 width=8)"
"        Output: created_time, ((created_time / 60))"
"        Sort Key: ((pm_server_stat.created_time / 60))"
"        ->  Seq Scan on public.pm_server_stat  (cost=0.00..34967.44 rows=1206435 width=8)"
"              Output: created_time, (created_time / 60)"

有谁知道为什么会这样?我怀疑类型可能不同?

4

1 回答 1

2

PostgreSQL 在 9.1 或更早版本中没有“覆盖”索引。这意味着无论如何它都必须访问这些行,在这种情况下它不妨扫描它们。它们将出现在 9.2 中(如果你想尝试的话,目前正在进行 beta 测试),但我不确定它们是否足够聪明。

一旦您想要“提供的总文件数”或“传输的总数据包数”,它就永远不会起作用。

通常,对于此类汇总任务,您将拥有一个或多个汇总表:stats_minute、stats_hour、stats_day、stats_week 等。您拥有多少取决于总数据大小/性能要求。使用简单的 cron-job 使摘要保持最新。如果数据将以“延迟”时间戳传入,您可能需要稍微滞后或允许重新计算。

然后,您可以将汇总表与自当前小时开始以来所有行的实际总和合并。要查询的数据要少得多,并且可以根据您的需要进行。

于 2012-08-17T18:49:53.590 回答