1

我目前正在使用更大的 wikipedia-dump 派生 PostgreSQL 数据库;它包含大约 40 GB 的数据。该数据库在装有 Suse Linux Enterprise Server 10 的 HP Proliant ML370 G5 服务器上运行;我通过一个简单的 D-Link 路由器管理的专用网络从我的笔记本电脑查询它。我为笔记本电脑和服务器分配了静态 DHCP(私有)IP。

无论如何,从我的笔记本电脑上,使用 pgAdmin III,我发送了一些 SQL 命令/查询;其中一些是 CREATE INDEX、DROP INDEX、DELETE、SELECT 等。有时我发送一个命令(如 CREATE INDEX),它返回,告诉我查询已完美执行等。但是,分配给这样一个命令似乎仍然在服务器上休眠。现在,我真的不介意这一点,因为我对自己说 PostgreSQL 维护着一个准备处理查询的 postmaster 池。然而,如果这个过程占用了 6 GB 的 9.4 GB 分配的 RAM,我会担心(目前确实如此)。现在也许这是保存在[共享]内存中的数据缓存,以防另一个查询碰巧需要使用相同的数据,但我不知道。

另一件事困扰着我。

我有 2 张桌子。一是表;我在其page_id列上有一个索引。另一个是具有 pl_from 列的pagelinks,该列在page.page_id列中没有引用任何内容或变量;与page_id列不同,pl_from还没有索引。为了让您了解表的规模以及我找到可行解决方案的必要性,表有 1340 万行(在我删除了我不需要的行之后),而pagelinks表有 2.93 亿行。

我需要执行以下命令来清理pagelinks表中一些无用的行:

DELETE FROM pagelinks USING page WHERE pl_from NOT IN (page_id);

所以基本上,我希望摆脱来自不在页表中的页面的所有链接的pagelinks表。即使在禁用嵌套循环和/或顺序扫描之后,查询优化器也总是给我以下“解决方案”:

Nested Loop  (cost=494640.60..112115531252189.59 rows=3953377028232000 width=6)
  Join Filter: ("outer".pl_from <> "inner".page_id)"
  ->  Seq Scan on pagelinks  (cost=0.00..5889791.00 rows=293392800 width=17)
  ->  Materialize  (cost=494640.60..708341.51 rows=13474691 width=11)
        ->  Seq Scan on page  (cost=0.00..402211.91 rows=13474691 width=11)

似乎这样的任务需要几个星期才能完成;显然,这是不可接受的。在我看来,我宁愿它使用page_id索引来做它的事情......但它是一个顽固的优化器,我可能错了。

4

3 回答 3

1

关于你的第二个问题;您可以尝试使用 CREATE TABLE AS 语句创建仅包含所需记录的新表;如果新表足够小,它可能会更快——但它也可能无济于事。

于 2009-01-05T21:14:22.473 回答
1

事实上,我决定创建一个临时表来加速查询执行:

CREATE TABLE temp_to_delete AS(
    (SELECT DISTINCT pl_from FROM pagelinks) 
        EXCEPT 
    (SELECT page_id FROM page));
DELETE FROM pagelinks USING temp_to_delete 
    WHERE pagelinks.pl_from IN (temp_to_delete.pl_from);

令人惊讶的是,这个查询在大约 4 小时内完成,而最初的查询在我决定杀死它之前保持活跃了大约 14 小时。更具体地说,删除返回:

Query returned successfully: 31340904 rows affected, 4415166 ms execution time.

至于我的问题的第一部分,似乎 postmaster 进程确实在缓存中保留了一些信息;当另一个查询需要不在缓存和一些内存 (RAM) 中的信息时,缓存将被清空。邮政局长确实只是一个流程池'。

我还想到gnome-system-monitor是一个神话,因为它提供不完整的信息并且在信息价值方面毫无价值。主要是因为这个应用程序,我最近一直很困惑;例如,它不考虑其他用户(如 postgres 用户!)的内存使用情况,甚至告诉我我还有 12 GB 的 RAM,但事实并非如此。因此,我尝试了几个系统监视器,因为我想知道 postgreSQL 是如何使用它的资源的,而且xosview似乎确实是一个有效的工具。

希望这可以帮助!

于 2009-01-06T00:48:45.223 回答
0

只要与客户端的连接打开,您的 postmaster 进程就会一直存在。pgadmin 是否关闭连接?我不知道。

使用的内存可以是 shared_buffers (检查您的配置设置),也可以不是。

现在,查询。对于像这样的大型维护操作,请随意将 work_mem 设置为像几 GB 这样的大值。你看起来有很多内存,所以使用它。

将 work_mem 设置为“4GB”;EXPLAIN DELETE FROM pagelinks WHERE pl_from NOT IN (SELECT page_id FROM page);

它应该 seq 扫描页面,对其进行散列,并 seq 扫描页面链接,查看散列以检查 page_ids。它应该很快(比 4 小时快得多!)但是你需要一个大的 work_mem 来存储哈希。

但是由于您删除了表的很大一部分,因此这样做可能会更快:

CREATE TABLE pagelinks2 AS SELECT a.* FROM pagelinks a JOIN pages b ON a.pl_from = b.page_id;

(您可以使用简单的 JOIN 而不是 IN)

您还可以在此查询上添加 ORDER BY,您的新表将在磁盘上很好地排序,以便以后进行最佳访问。

于 2009-10-27T23:25:30.210 回答