2012-12-03 87 views
1

我有一个PostgreSQL数据库,其中包含大量行〜160,000,000。数据库基本上是一组网络日志。有一个称为时间的列是时间戳。基本上每个独特的时间都有一个网络上每台机器的日志。因此有多行具有相同的时间戳记。即PostgreSQL索引性能问题

time ip    value 
2:00 192.168.1.1 5 
2:00 192.168.1.2 4 
2:00 192.168.1.3 5 
3:00 192.168.1.1 3 
3:00 192.168.1.2 5 
3:00 192.168.1.3 2 
etc  etc 

现在我已经创建了这个数据库的时间索引,因为这是我总是查询关系的字段。

i.e. select * from networklogs where time = '2:00' and value = 5 

由于查询必须扫描整个数据库,所以不使用索引,每个查询大约需要2分钟。我创建了索引,以便我的查询将查找包含匹配时间的数据子集,然后基于来自此处的另一个值进行过滤,因此我希望查询速度更快。

但是查询现在似乎需要更长的时间......

这很奇怪,因为在pgAdmin的它解释说,查询将使用时间指数和时间指数从总缩小数据〜800000件160,000,000,然后查询过滤器将该数据缩小到1,700个项目。这个解释需要17ms,但是如果我运行查询需要3分钟。

这应该比搜索160,000,000个项目上的两个匹配标准更快!

我不知道为什么它不会更快,我想知道是否即使pgAdmin解释查询为使用时间索引,它实际上使用它时执行查询吗?

有没有人有任何想法或建议?

谢谢, 詹姆斯

更新:我已经运行EXPLAIN分析其对以下命令:

explain analyze select latitude,longitude from networklogs where value = 5 and time = '2:00' 

的结果是:

"Bitmap Heap Scan on networklogs (cost=13178.17..1488620.94 rows=848 width=19) (actual time=3507.923..278760.509 rows=33 loops=1)" 
" Recheck Cond: (time = '2:00'::timestamp without time zone)" 
" Rows Removed by Index Recheck: 38302021" 
" Filter: (value = 5)" 
" Rows Removed by Filter: 882873" 
" -> Bitmap Index Scan on timeindex (cost=0.00..13177.95 rows=530111 width=0) (actual time=695.771..695.771 rows=882906 loops=1)" 
"  Index Cond: (time = '2:00'::timestamp without time zone)" 
"Total runtime: 278764.148 ms" 
+0

尝试VACUUM ANALYZE。 – randomguy

+0

谢谢,现在就试试吧! –

+0

你有什么特权从某个时间点备份旧数据,只保留最近的数据量? – bonCodigo

回答

3

如果这些主要是您要执行搜索的参数,我会建议在它们上创建一个多重索引。因为在你的实际情况下,数据库有一个时间索引,所以它能够知道哪些行匹配这个条件,但是它必须从索引给出的所有不同位置获取它们,然后检查次要条件。

CREATE INDEX time_and_value ON networklogs (time, value); 

使用该索引,数据库就不必为了检查另一条件数据提取,它会简单地获取它知道已经符合搜索条件的数据。订单当然很重要。

我看你使用的是经纬度数据,可能使用point型将是很好的,如此你就可以使用所有都默认使用的Postgres的geometric operators。这些数据也可以编入索引。

+0

查看EXPLAIN输出,'time'索引在0.7秒内匹配882,906行。然后数据库需要27.1秒才能获取所有这些行(可能是因为[大量磁盘搜索](http://stackoverflow.com/a/13236089/1026671)),仅丢弃了其中的99.996%。你肯定需要在两列上都有一个索引。 – willglynn

+0

对不起,这是278秒(3.16毫秒/行),而不是27秒。听起来像随机读取给我。 – willglynn

+0

感谢您的答案。那么我需要创建几个多重索引,这可能吗?例如,我的实际数据库有比上面显示的示例更多的列。我会需要一些像时间和价值,时间&国旗,时间&noconn等指标... –

2

PostgreSQL有EXPLAIN and EXPLAIN ANALYZE研究如何查询运行。 PG Admin很可能使用EXPLAIN来告诉你查询将如何运行;您可以使用EXPLAIN ANALYZE获得更准确的结果,它实际运行查询并从实际运行中生成统计信息。你至少可以看到时间花在什么地方,即使它按照预期使用索引。

+0

谢谢,现在就试试吧! –

+0

我运行解释分析,但请你向我解释这是什么意思:“网络日志上的位图堆扫描(成本= 13178.17..1488620.94行= 848宽度= 19)(实际时间= 3507.923..278760.509行= 33循环= 1)“'就时间和行动而言?这是从输出的第一行的方式... –

+0

完整输出已添加到我的原始文章作为更新。 –