PostgreSQL führt jede Abfrage in einem einzigen Backend aus, was ein Prozess mit einem einzelnen Thread ist. Es kann nicht mehr als eine CPU für eine Abfrage verwenden. Es ist auch etwas eingeschränkt, was E/A-Parallelität innerhalb einer einzelnen Abfrage erreichen kann, wobei es nur gleichzeitige I/O für Bitmap-Index-Scans durchführt und sich ansonsten auf das Betriebssystem und das Plattensystem für gleichzeitige I/O verlässt.
Pg ist gut bei gleichzeitigen Abfragen vieler kleinerer Abfragen und es ist einfach, Ihr System auf diese Weise zu sättigen, es ist einfach nicht so gut, das Beste aus Systemressourcen für eine oder zwei wirklich große Abfragen zu machen.
Was Sie tun können, ist, den Job in Stücke aufzuteilen und sie an Arbeiter zu verteilen. Sie haben dazu anspielte mit:
Kann ich Abfrage ändern, um postgre zu erhalten GetStatistic in paralel für verschiedene Zeilen gleichzeitig zu berechnen, alle verfügbaren CPUs?
Es gibt eine Vielzahl von Werkzeugen, wie DBlink, PL/Proxy, pgbouncer und PgPool-II die entworfen sind, mit dieser Art von Arbeit zu helfen. Alternativ können Sie es auch selbst tun, indem Sie (zum Beispiel) 8 Worker starten, die sich jeweils mit der Datenbank verbinden und UPDATE ... WHERE id BETWEEN ? AND ?
Anweisungen mit nicht überlappenden ID-Bereichen ausführen. Eine ausgeklügeltere Option besteht darin, dass ein Warteschlangen-Controller Bereiche von ungefähr 1000 IDs an Arbeiter verteilt, die dann diesen Bereich anfordern und dann nach einem neuen fragen.
Beachten Sie, dass 64 CPUs nicht bedeutet, dass 64 gleichzeitige Arbeiter ideal ist. Ihre Festplatten-E/A ist auch ein Faktor, wenn es um Schreibvorgänge geht. Sie können Ihren E/A-Kosten ein wenig helfen, wenn Sie Ihre UPDATE
Transaktionen verwenden, um eine commit_delay
zu verwenden, und (wenn für Ihre Geschäftsanforderungen für diese Daten sicher) synchronous_commit = 'off'
dann die Last von Syncs sollte erheblich reduziert werden. Nichtsdestoweniger ist es wahrscheinlich, dass der beste Durchsatz deutlich unter 64 gleichzeitigen Arbeitern erreicht wird.
Es ist sehr wahrscheinlich, dass Ihre GetStatistic
-Funktion viel schneller gemacht werden kann, indem Sie sie in eine inlineable SQL-Funktion oder View konvertieren, anstatt eine Schleife-schwere prozedurale PL/pgSQL-Funktion ist es im Moment. Es könnte hilfreich sein, wenn Sie diese Funktion angezeigt haben.
Warum eine Funktion verwenden, gibt es etwas, das nicht durch einfaches SQL erreicht werden kann? Benötigt die Funktion nur Werte aus der aktuellen Zeile oder bezieht sie sich auch auf andere Datenquellen (: = Tabellen)? BTW: zeigen Sie uns die Funktion. – wildplasser
Überprüfen Sie den Plan dieser Abfrage, Sie werden sehen, dass diese Funktion 10M mal aufgerufen wird. Vielleicht wäre es besser, es in reinem SQL zu schreiben und es könnte viel schneller sein. –