Postgres没有使用“created_time / 60”的索引

时间:2012-08-17 18:30:53

标签: postgresql indexing performance

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

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

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)"

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

1 个答案:

答案 0 :(得分:2)

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

无论如何,一旦你想要“提供的文件总量”或“传输的总包数量”,它将永远不会工作。

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

然后,您可以将摘要表的联合与自当前小时开始以来所有行的实际总和相关联。这要查询的数据要少得多,并且可以尽可能快地进行查询。