Frage

Ich arbeite derzeit mit einer größeren wikipedia-Dump abgeleitet PostgreSQL-Datenbank; Es enthält etwa 40 GB Daten. Die Datenbank läuft auf einem HP Proliant ML370 G5 Server mit Suse Linux Enterprise Server 10; Ich abfragt es von meinem Laptop über ein privates Netzwerk mit einem einfachen D-Link-Router verwaltet. I zugeordnet statische DHCP (privat) IPs sowohl Laptop und Server.

Wie auch immer, von meinem Laptop, mit pgAdmin III, sende ich einige SQL-Befehle / Abfragen aus; einige davon sind CREATE INDEX, DROP INDEX, DELETE, SELECT usw. Manchmal schicke ich einen Befehl (wie CREATE INDEX), gibt es, mir zu sagen, dass die Abfrage perfekt ausgeführt wurde, usw. Aber der Postprozess ein solches zugewiesen Befehl scheint auf dem Server schlafen zu bleiben. Nun, ich weiß nicht wirklich um diese kümmern, denn ich zu mir selbst sagen, dass PostgreSQL einen Pool von Webmastern bereit hält Anfragen zu verarbeiten. Doch wenn dieser Prozess frisst 6 GB davon 9,4 GB zugewiesen RAM, bin ich sehr besorgt (und es tut dies für den Moment). Nun, vielleicht ist dies ein Cache von Daten, die in [geteilt] Speicher im Falle gehalten wird eine weitere Abfrage zu müssen kommt vor, dass dieselben Daten verwenden, aber ich weiß es nicht.

Eine andere Sache stört mich.

Ich habe 2 Tabellen. Eine davon ist die Seite Tabelle; Ich habe einen Index für seine page_id Spalte. Die andere ist die pagelinks Tabellen, die die pl_from Spalte, die Verweise entweder nichts oder eine Variable in der page.page_id Spalte hat; im Gegensatz zu den page_id Spalte, die pl_from hat keinen Index (noch) nicht. Um Ihnen eine Vorstellung von der Größenordnung der Tabellen und der Notwendigkeit für mich, eine tragfähige Lösung zu finden, die Seite Tabelle hat 13,4 Millionen Zeilen (nachdem ich diejenigen gelöscht brauche ich nicht), während die pagelinks Tabelle hat 293 Millionen.

Ich brauche den folgenden Befehl ausführen reinigen die pagelinks Tabelle einiger ihrer nutzlosen Zeilen:

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

Also im Grunde möchte ich die pagelinks Tabelle aller Links von einer Seite kommt befreien nicht in der Seite Tabelle. Auch nach den verschachtelten Schleifen und / oder sequentiellen Scans deaktivieren, die Abfrage-Optimierer gibt mir immer die folgende „Lösung“:

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)

Es scheint, dass eine solche Aufgabe mehr dauern würde, als Wochen abzuschließen; Offensichtlich ist dies nicht akzeptabel. Es scheint mir, dass ich würde viel lieber es verwenden, um den page_id Index seine Sache zu tun ... aber es ist ein hartnäckiger Optimierer und ich könnte falsch sein.

War es hilfreich?

Lösung 2

Tatsächlich habe ich beschlossen, eine temporäre Tabelle erstellen Abfrageausführung zu beschleunigen:

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);

Überraschenderweise diese Abfrage in etwa 4 Stunden abgeschlossen, während die erste Abfrage für etwa 14h aktiv geblieben war, bevor ich sie zu töten entschieden. Genauer gesagt, löschen Sie die zurückgegeben:

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

Was den ersten Teil meiner Frage, so scheint es, dass der Postprozess in der Tat einige Informationen im Cache hält; wenn eine andere Abfrage Informationen nicht im Cache und etwas Speicher (RAM) benötigt, wird der Cache geleert. Und die Postmeister sind in der Tat, aber ein Pool von Prozess.

Es ist aufgetreten mir auch, dass der gnome-system-monitor ist ein Mythos für sie unvollständige Informationen verursacht und sind in Informationswert wertlos. Es ist vor allem aufgrund dieser Anwendung, die ich in letzter Zeit so verwirrt gewesen sein; zum Beispiel, hält sie nicht die Speichernutzung von anderen Benutzern (wie der Postgres-Benutzer!) und sogar sagt mir, dass ich 12 GB RAM halten kann, wenn dies so nicht stimmt. Daher habe ich versucht, ein paar System-Monitore für die I wissen, wie postgreSQL seine Ressourcen verwendet, und es scheint, dass xosview ist in der Tat ein geeignetes Instrument.

Hope, das hilft!

Andere Tipps

Um Ihre zweite Frage; Sie könnten versuchen, mit nur den Aufzeichnungen eine neue Tabelle erstellen Sie mit einer CREATE TABLE AS Anweisung müssen; wenn die neue Tabelle ausreichend klein ist, könnte es faster- sein, aber es könnte auch nicht helfen.

Ihr Postmeister Prozess wird dort bleiben, solange die Verbindung zum Client geöffnet ist. Ist pgAdmin die Verbindung schließen? Ich weiß es nicht.

Speicher verwendet wird, könnte shared_buffers (überprüfen Sie Ihre Konfigurationseinstellungen) oder nicht.

Nun wird die Abfrage. Für große Wartungsarbeiten wie diese, fühlen Sie sich frei work_mem etwas groß wie ein paar GB einzustellen. Sie sehen aus wie Sie viel RAM bekamen, so dass es verwendet werden.

gesetzt work_mem zu '4GB'; EXPLAIN VON pagelinks DELETE WHERE pl_from NOT IN (SELECT page_id FROM Seite);

Es sollte seq Scan Seite, hash es, und seq Scan pagelinks, in dem Hash späht für page_ids zu überprüfen. Es sollte recht schnell (viel schneller als 4 Stunden!), Aber Sie müssen eine große work_mem für den Hash.

Da du aber einen wesentlichen Teil der Tabelle löschen, kann es schneller sein, es so zu tun:

TABLE pagelinks2 as a SELECT * FROM a Seiten b ON a.pl_from = b.page_id JOIN pagelinks;.

(Sie einen einfachen JOIN statt IN verwenden könnte)

Sie können auch eine ORDER BY auf dieser Abfrage hinzufügen, und Ihre neue Tabelle schön auf der Festplatte bestellt werden für einen optimalen Zugang später.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top