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

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

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

现在已经有一个小时了。事实上,邮政局长似乎正在越来越多地占用我非常有限的高清空间。我认为它现在吃了大约20 GB。我以前玩过postgresql.conf文件,以便为它提供更高的性能灵活性(即让它使用更多的资源),因为它运行12 GB的RAM。我认为我基本上将大多数字节和这个文件的相关变量翻了四倍,以为它会使用更多的RAM来完成它的工作。

然而,db似乎没有使用太多RAM。使用Linux系统监视器,我能够看到postmaster使用1.6 GB的共享内存(RAM)。无论如何,我想知道你们是否可以帮助我更好地理解它在做什么似乎我真的不明白 PostgreSQL如何使用高清资源

关于维基百科数据库的元结构,它们提供了一个很好的架构可能对您有用甚至感兴趣。

请随时向我询问更多详情。

有帮助吗?

解决方案

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

假设每行占用100个字节的空间,即29,500,000,000字节,或大约30 GB的存储空间。它无法适应内存中的所有内容,因此您的系统会颠簸,从而使操作速度降低1000倍或更多。如果正在使用交换文件,您的高清空间可能会消失在交换空间中。

如果您只需要进行一次此计算,请尝试将其拆分为较小的数据子集。假设pl_namespace是数字并且范围从1-295百万,请尝试这样的事情:

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

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

其他提示

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

您是否在 pl_namespace 列上有索引?如果有很多不同的结果,我可以想象查询在没有索引的2.95亿行表上相当沉重。话虽如此,吞下10GB是一件非常糟糕的事情。你知道它写的是哪些文件吗?

好的,这就是它的要点:

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

修改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亿页面链接(这是他们为调查所做的)。

当命令返回结果集时,所有临时表都会被自动删除,就像没有发生任何事情一样。

谢谢你的帮助!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top