2

我刚刚完成了尽可能多的关于维基百科(英语)的链接结构数据的传输。基本上,我从维基百科的最新转储存储库下载了一堆 SQL 转储。由于我使用的是 PostgreSQL 而不是 MySQL,因此我决定使用管道 shell 命令将所有这些转储加载到我的数据库中。

无论如何,其中一张表有 2.95 亿行:pagelinks表;它包含所有内部 wiki 超链接。从我的笔记本电脑上,使用 pgAdmin III,我将以下命令发送到我的数据库服务器(另一台计算机):

SELECT pl_namespace, COUNT(*) FROM pagelinks GROUP BY (pl_namespace);

它已经在那里待了一个小时左右。问题是邮政局长似乎越来越多地占用我非常有限的高清空间。我认为到目前为止它吃了大约 20 GB。我之前曾使用过 postgresql.conf 文件,以便为它提供更大的性能灵活性(即让它使用更多资源),因为它使用 12 GB 的 RAM 运行。我想我基本上将这个文件的大多数字节和这些相关变量增加了四倍,认为它会使用更多的 RAM 来完成它的工作。

但是,数据库似乎并没有使用太多 RAM。使用 Linux 系统监视器,我可以看到 postmaster 正在使用 1.6 GB 的共享内存 (RAM)。无论如何,我想知道你们是否可以帮助我更好地理解它在做什么,因为我似乎真的不明白PostgreSQL 如何使用 HD 资源

关于 wikipedia 数据库的元结构,它们提供了一个很好的模式,可能有用,甚至你感兴趣。

请随时向我询问更多详细信息,谢谢。

4

3 回答 3

3

这可能是导致问题的 GROUP BY。为了进行分组,数据库必须对行进行排序以将重复项放在一起。索引可能无济于事。粗略计算:

假设每行占用 100 字节空间,即 29,500,000,000 字节,或大约 30GB 的存储空间。它无法将所有这些都放入内存中,因此您的系统正在抖动,这会使操作速度减慢 1000 倍或更多。如果它正在使用交换文件,您的 HD 空间可能会消失在交换空间中。

如果您只需要执行一次此计算,请尝试将其分解为更小的数据子集。假设 pl_namespace 是数字且范围为 1-2.95 亿,请尝试以下操作:

SELECT pl_namespace, COUNT(*)
FROM pagelinks
WHERE pl_namespace between 1 and 50000000
GROUP BY (pl_namespace);

然后对 50000001-100000000 执行相同的操作,依此类推。使用 UNION 将您的答案组合在一起,或者使用外部程序简单地将结果制成表格。忘记我写的关于索引对 GROUP BY 没有帮助的内容;在这里,索引将有助于 WHERE 子句。

于 2009-01-03T21:25:01.813 回答
1

究竟是什么声称它只占用 9.5MB 的 RAM?这在我看来不太可能——共享内存几乎可以肯定在不同 Postgres 进程之间共享的 RAM。(据我记得,每个客户最终都是一个单独的进程,虽然已经有一段时间了,所以我可能会错。)

pl_namespace列上有索引吗?如果有大量不同的结果,我可以想象在没有索引的 2.95 亿行表上查询会非常繁重。话虽如此,10GB 的容量实在是太大了。你知道它正在写入哪些文件吗?

于 2009-01-03T20:27:50.807 回答
0

好的,这是它的要点:

GROUP BY 子句使索引无效,因此 postmaster(postgresql 服务器进程)决定创建一组位于 $PGDATA/base/16384/pgsql_tmp 目录中的表(23GB 表)。

在修改 postgresql.conf 文件时,我已允许 postgreSQL 使用 1.6 GB 的 RAM(我现在将它加倍,因为它可以访问 11.7 GB 的 RAM);postmaster 进程确实使用了 1.6 GB 的 RAM,但这还不够,因此 pgsql_tmp 目录。

正如 Barry Brown 所指出的,由于我只是执行此 SQL 命令来获取有关pagelinks.namespaces之间链接分布的一些统计信息,因此我可以查询 2.96 亿个页面链接中的一个子集这就是他们所做的用于调查)。

当命令返回结果集时,所有临时表都被自动删除,就好像什么都没发生一样。

谢谢你们的帮助!

于 2009-01-03T21:43:02.557 回答