2009-01-05 35 views
1

我目前正在使用更大的維基百科 - 轉儲派生PostgreSQL數據庫;它包含大約40 GB的數據。該數據庫使用Suse Linux Enterprise Server 10在HP Proliant ML370 G5服務器上運行;我通過由簡單的D-Link路由器管理的專用網絡從我的筆記本電腦查詢它。我將靜態DHCP(專用)IP分配給筆記本電腦和服務器。PosgreSQL查詢優化和Postmaster過程'

不管怎樣,我的筆記本電腦,使用的pgAdmin III,我送了一些SQL命令/查詢;其中一些是CREATE INDEX,DROP INDEX,DELETE,SELECT等。有時我發送一個命令(如CREATE INDEX),它會返回,告訴我查詢完美執行等等。但是,postmaster進程分配給了這樣一個命令似乎仍然在服務器上休眠。現在,我並不介意這一點,因爲我對自己說,PostgreSQL維護一個準備處理查詢的郵件管理員池。然而,如果這個過程耗盡了6 GB的9.4 GB分配的內存,我擔心(現在這樣做)。現在,也許這是一個保存在[共享]內存中的數據緩存,以防其他查詢碰巧需要使用相同的數據,但我不知道。

另一件事是困擾我。

我有2個表格。一個是頁面表;我在page_id列中有一個索引。另一個是頁面鏈接表,其中有pl_from列,該列在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索引來做它的事情......但它是一個固執的優化器,我可能是錯的。

有什麼想法?

回答

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小時保持活躍之前,我決定殺它。更具體地說,DELETE返回:

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

至於我的問題的第一部分,似乎postmaster進程確實在緩存中保留了一些信息;當另一個查詢不需要緩存和某些內存(RAM)中的信息時,緩存將被清空。而這些郵政管理人員確實只是一個過程池「。

我也想到,gnome系統監視器是一個神話,因爲它給出了不完整的信息,在信息價值中毫無價值。這主要是由於這個應用程序,我最近一直很困惑;例如,它不考慮其他用戶(如postgres用戶!)的內存使用情況,甚至會告訴我,如果這種情況不真實,我還剩下12 GB的內存。因此,我嘗試了幾個系統監視器,因爲我想知道postgreSQL如何使用它的資源,並且似乎確實是一個有效的工具。

希望這會有所幫助!

1

對於第二個問題;您可以嘗試用CREATE TABLE AS語句創建一個只包含所需記錄的新表;如果新表格足夠小,它可能會更快 - 但它也可能沒有幫助。

+0

其實,這就是我想爲它看起來像我最好的鏡頭。如果有效,我會公佈結果。謝謝! – 2009-01-05 21:52:12

0

只要與客戶端的連接處於打開狀態,您的postmaster進程就會停留在那裏。 pgadmin關閉連接嗎?我不知道。

使用的內存可能是shared_buffers(檢查您的配置設置)或不。

現在,查詢。對於像這樣的大型維護操作,請隨意將work_mem設置爲像GB這樣的大型文件。你看起來像你有很多的RAM,所以使用它。

將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選擇一個* FROM pagelinks一個JOIN網頁B關於a.pl_from = B。 PAGE_ID;

(你可以使用一個簡單連接代替)

您也可以在此查詢添加一個ORDER BY,和你的新表將很好地下令在磁盤上的最佳接入以後。