我目前正在使用更大的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),它返回,告诉我查询是否完美执行等等。但是,postmaster进程分配给了这样一个命令似乎仍在服务器上休眠。现在,我并不介意这一点,因为我告诉自己,PostgreSQL维护着一个准备好处理查询的邮件管理员池。然而,如果这个过程占用了6 GB的9.4 GB内存RAM,我担心(目前这样做)。现在也许这是一个保存在[共享]内存中的数据缓存,以防另一个查询碰巧需要使用相同的数据,但我不知道。

另一件事困扰着我。

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

我需要执行以下命令来清除某些无用行的 pagelinks 表:

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

所以基本上,我希望摆脱来自不在 page 表中的页面的所有链接的 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 索引来做它的事情......但它是一个顽固的优化器,我可能是错的。

有帮助吗?

解决方案 2

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

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小时。更具体地说,DELETE返回:

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

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

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

希望这有帮助!

其他提示

至于你的第二个问题;您可以尝试使用CREATE TABLE AS语句创建一个只包含所需记录的新表;如果新表格足够小,它可能会更快 - 但它也可能没有帮助。

只要与客户端的连接已打开,您的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,并且您的新表将在磁盘上良好排序,以便以后获得最佳访问权限。

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