Frage

Ich habe auf einem Tisch eine UPDATE ausgeführt wird, die 250 Millionen Zeilen mit 3 Index '; Dieses Update verwendet eine andere Tabelle 30 Millionen Zeilen enthält. Es wurde nun für etwa 36 Stunden ausgeführt wird. Ich frage mich, ob sie ein Weg ist, um herauszufinden, wie nahe es ist zu getan, wenn es eine Million Tage dauern plant, seine Sache zu tun, ich es töten; doch wenn es nur ein oder zwei Tage braucht, werde ich laufen lassen. Hier ist der Befehl Abfrage:

UPDATE pagelinks SET pl_to = page_id
    FROM page
    WHERE 
        (pl_namespace, pl_title) = (page_namespace, page_title)
        AND
        page_is_redirect = 0
;

Die EXPLAIN ist hier nicht das Thema und ich erwähne nur die um mehrere Indizes in mit dem großen Tisch zu etwas zu rechtfertigen, wie lange es sie aktualisieren dauert. Aber hier ist die EXPLAIN trotzdem:

Merge Join  (cost=127710692.21..135714045.43 rows=452882848 width=57)
  Merge Cond: (("outer".page_namespace = "inner".pl_namespace) AND ("outer"."?column4?" = "inner"."?column5?"))
  ->  Sort  (cost=3193335.39..3219544.38 rows=10483593 width=41)
        Sort Key: page.page_namespace, (page.page_title)::text
        ->  Seq Scan on page  (cost=0.00..439678.01 rows=10483593 width=41)
              Filter: (page_is_redirect = 0::numeric)
  ->  Sort  (cost=124517356.82..125285665.74 rows=307323566 width=46)
        Sort Key: pagelinks.pl_namespace, (pagelinks.pl_title)::text"
        ->  Seq Scan on pagelinks  (cost=0.00..6169460.66 rows=307323566 width=46)

Jetzt auch ich schickte einen parallelen Abfrage-Befehl, um einen von DROP pagelinks Indizes; natürlich ist es wartet auf die UPDATE bis zum Ende (aber ich habe das Gefühl, es trotzdem versuchen!). Daher kann ich nichts SELECT von pagelinks aus Angst, die Daten korrumpieren (es sei denn, Sie denken, es wäre sicher die DROP INDEX Postmeister Prozess zu töten?).

Also ich frage mich, ob sie eine Tabelle, die den Überblick über die Menge der toten Tupeln oder etwas halten würde, es wäre schön zu wissen, wie schnell oder wie weit das UPDATE ist bei der Fertigstellung seiner Aufgabe.

Thx (PostgreSQL ist nicht so intelligent, wie ich dachte, es braucht Heuristiken)

War es hilfreich?

Lösung

Haben Sie die PostgreSQL-Dokumentation „ ERKLÄREN Mit “, die Ausgabe Sie zeigt?

zu interpretieren

Ich bin kein regelmäßiger PostgreSQL-Benutzer, aber ich habe gerade gelesen, dass doc, und dann im Vergleich zum EXPLAIN Ausgang Sie zeigt. Ihre UPDATE Abfrage scheint keine Indizes zu verwenden, und es ist gezwungen, Tisch-Scans zu tun, sowohl page und pagelinks zu sortieren. Die Art besteht kein Zweifel, groß genug, um temporäre Plattendateien zu müssen, was ich denke, werden unter Ihrem temp_tablespace erstellt.

Dann sehe ich die geschätzten Datenbankseiten zu lesen. Das Top-Level der EXPLAIN Ausgabe sagt (cost=127710692.21..135714045.43). Die Einheiten sind hier in Disk-I / O-Zugriffe. Es wird also die Scheibe über 135 Millionen Mal den Zugriff auf diese UPDATE zu tun.

Hinweis

, dass sogar 10.000 U Scheiben mit 5 ms Zugriffszeit kann im besten Fall 200 I / O-Operationen pro Sekunde unter optimalen Bedingungen erreichen. Dies würde bedeuten, dass Ihre UPDATE 188 Stunden dauern würden (7,8 Tage) der Disk-I / O, auch wenn Sie gesättigte Disk-I / O für diesen Zeitraum aufrechterhalten konnten (das heißt kontinuierlich liest / schreibt ohne Pausen). Das ist unmöglich, und ich würde die tatsächliche Durchsatz erwarten von mindestens einer Größenordnung aus sein, zumal Sie haben ohne Zweifel für alle möglichen anderen Arbeiten in der Zwischenzeit auf diesen Server im Einsatz. Also ich würde vermuten, Sie nur ein Bruchteil des Weges durch Ihre UPDATE sind.

Wenn es nach mir ginge, würde ich diese Abfrage am ersten Tag getötet, und fand einen anderen Weg, um die UPDATE der Durchführung, die eine bessere Nutzung der Indizes gemacht und nicht auf der Festplatte Sortierung erfordern. Sie können sich wahrscheinlich in einer einzigen SQL-Anweisung nicht.

Wie für Ihre DROP INDEX, würde ich denke, es ist einfach blockt, für den exklusiven Zugriff auf den Tisch warten, und während es in diesem Zustand ist ich glaube, Sie es wahrscheinlich töten kann.

Andere Tipps

Das ist sehr alt, aber wenn Sie einen Weg wollen Sie Ihr Update auf Monitore ... Denken Sie daran, dass Sequenzen weltweit betroffen sind, so können Sie einfach erstellen Sie dieses Update in einer anderen Sitzung Monitore, indem Sie diese:

create sequence yourprogress; 

UPDATE pagelinks SET pl_to = page_id
    FROM page
    WHERE 
        (pl_namespace, pl_title) = (page_namespace, page_title)
        AND
        page_is_redirect = 0 AND NEXTVAL('yourprogress')!=0;

Dann in einer anderen Sitzung nur das tun (keine Sorge über Transaktionen, wie Sequenzen global betroffen sind):

select last_value from yourprogress;

Dies wird zeigen, wie viele Zeilen betroffen sind, so können Sie abschätzen, wie lange es dauern.

Mit gerade einmal die Sequenz neu starten Ende noch einmal zu tun:

alter sequence yourprogress restart with 1;

Oder legen Sie es einfach:

drop sequence yourprogress;

Sie müssen Indizes oder, wie Bill darauf hingewiesen, muss es sequenzielle Scans auf allen Tabellen tun.

CREATE INDEX page_ns_title_idx on page(page_namespace, page_title);
CREATE INDEX pl_ns_title_idx on pagelink(pl_namespace, pl_title);
CREATE INDEX page_redir_idx on page(page_is_redirect);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top