2012-07-28 91 views
0

我是SQL/RDBMS的新手。libpq数据库非常慢(2000万条记录)

我有一个应用程序,它使用libpq库在PostgreSQL服务器中添加10列的行。现在,我的服务器与我的visual C++应用程序在同一台机器上运行。

我已经添加了大约15-20万条记录。使用select count(*) from <tableName>;获取总数的简单查询需要4-5分钟。

我用我输入数据(时间码)的时间索引了我的表格。大多数时候我需要添加不同的WHERE/AND条款。

有什么办法可以让事情变得更快吗?我需要尽可能快地做到这一点,因为一旦服务器移动到网络,事情将变得更慢。

谢谢

+1

什么版本的Postgres你在吗? – Kuberchaun 2012-07-28 13:52:25

+0

@garfield每当你[发布一个问题](http://stackoverflow.com/questions/11650018/libpq-code-to-create-list-and-delete-databases-c-vc-postgresql),有人问你为您的PostgreSQL版本。这不是你提出问题时应该把它放进去吗? – 2012-07-28 14:50:24

+0

硬件必须有问题。 “count(*)”的5分钟太长了。 – 2012-07-28 16:19:42

回答

2

我不认为网络延迟将是您的查询需要多长时间的一个重要因素。所有的处理都在PostgreSQL服务器上完成。

PostgreSQL MVCC设计意味着表格中的每一行(不仅仅是索引)必须被执行以计算计数(*),这是一项昂贵的操作。在你的情况下,涉及到很多行。

关于此主题有一个很好的维基页面http://wiki.postgresql.org/wiki/Slow_Counting有建议。从这个链接

两个建议,一个是使用一个索引列:

select count(index-col) from ...; 

...虽然在某些情况下这仅适用。

如果你有一个以上的指标,看看哪一个都有用最少的成本:

EXPLAIN ANALYZE select count(index-col) from ...; 

如果你可以用一个近似值生活,另一个是使用Postgres的特定功能像一个近似值:

select reltuples from pg_class where relname='mytable'; 

有多好这近似是取决于设置的频率自动清理运行等诸多因素;看到评论。

+0

但这可以帮助我获取总表的数量。在表项中,我有一个顺序增加长整数的列。总数将等于最后一行的那一列的值。这可以做很多优化。但是当我的查询中添加“where”和“and”时,情况就会变得更糟。 此外,如果我在“count(...)”中提供了列名,那么postgre必须通过所有列来计算数量,它将如何产生影响。 – Garfield 2012-07-28 12:17:22

+0

如果您的列被编入索引,PG将只需要对索引条目进行计数 - 而不是整个表格行。另外,放置where子句将限制行,并加快速度。试试看。您可以尝试不同的索引+ EXPLAIN ANALYZE来查看它们的效果。 – pd40 2012-07-28 12:18:52

+0

@Garfield当你说“按顺序递增长整数”时,你是指'SEQUENCE'还是'SERIAL' /'BIGSERIAL'?因为他们可能有空隙或漏洞。即使您从未删除过一行,最大ID也不一定等于行数。每当你做一个INSERT,然后回滚这个事务,你就会抛出生成的ID,留下一个洞。孔也可以以其他方式发生。 'max(id)'不是**与'serial(count)'是同一个事物。 – 2012-07-28 14:47:12

1

考虑pg_relation_size('tablename')并通过

select count(*) from tablename 

花秒做这个表的完全扫描时,这将会给您的磁盘(S)的吞吐量将其分摊。如果它太低,你首先要专注于改善这一点。 拥有良好的I/O子系统和良好的操作系统磁盘缓存对数据库至关重要。

默认的postgres配置意味着不会消耗太多资源来与其他应用程序配合使用。根据您的硬件和机器的整体利用率,您可能需要调整几个性能参数,如shared_buffers,effective_cache_sizework_mem。请参阅您的特定版本的文档以及wiki的performance optimization页面。

另请注意,select count(*)式查询的速度与libpq或网络无关,因为只有一个结果行被检索到。它完全发生在服务器端。

+0

它也可以放缓表膨胀,所以要留意。确保autovacuum经常运行,如果你做了很多'更新'和'删除'。 – 2012-07-29 02:17:39

0

您没有说明您的数据是什么,但通常情况下,处理大量数据的表的原因是对表进行分区。 http://www.postgresql.org/docs/9.1/static/ddl-partitioning.html

这不会加速您的select count(*) from <tableName>;查询,甚至可能会减慢查询速度,但如果您通常只对表中的部分数据感兴趣,这可能会有帮助。

相关问题