Neben der Einsparung des Aufwands für das Verbinden und Trennen, wo dies sonst bei jeder Anforderung durchgeführt wird, kann ein Verbindungspooler eine große Anzahl von Clientverbindungen auf eine kleine Anzahl tatsächlicher Datenbankverbindungen reduzieren. In PostgreSQL liegt die optimale Anzahl aktiver Datenbankverbindungen normalerweise irgendwo bei ((2 * core_count) + Effective_spindle_count) . Oberhalb dieser Zahl verschlechtern sich Durchsatz und Latenz.
Manchmal sagen Leute:"Ich möchte 2000 Benutzer mit schneller Reaktionszeit unterstützen." Es ist ziemlich sicher, dass die Leistung schrecklich sein wird, wenn Sie dies mit 2000 tatsächlichen Datenbankverbindungen versuchen. Wenn Sie einen Computer mit vier Quad-Core-Prozessoren haben und der aktive Datensatz vollständig zwischengespeichert ist, werden Sie eine viel bessere Leistung für diese 2000 Benutzer feststellen, indem Sie die Anforderungen durch etwa 35 Datenbankverbindungen leiten.
Um zu verstehen, warum das so ist, soll dieses Gedankenexperiment helfen. Stellen Sie sich einen hypothetischen Datenbankserver vor, der nur eine Ressource gemeinsam nutzen kann – einen einzelnen Kern. Dieser Kern teilt alle gleichzeitigen Anforderungen ohne Overhead gleichmäßig in Zeitscheiben ein. Nehmen wir an, 100 Anfragen gehen alle gleichzeitig ein, von denen jede eine Sekunde CPU-Zeit benötigt. Der Kern arbeitet an allen von ihnen und schneidet sie in Zeitscheiben, bis sie alle 100 Sekunden später fertig sind. Überlegen Sie nun, was passiert, wenn Sie einen Verbindungspool voranstellen, der 100 Client-Verbindungen akzeptiert, aber jeweils nur eine Anfrage an den Datenbankserver stellt und alle Anfragen, die eintreffen, während die Verbindung ausgelastet ist, in eine Warteschlange stellen. Wenn jetzt 100 Anfragen gleichzeitig eintreffen, erhält ein Client in 1 Sekunde eine Antwort; ein anderer erhält eine Antwort in 2 Sekunden und der letzte Client erhält eine Antwort in 100 Sekunden. Niemand musste länger auf eine Antwort warten, der Durchsatz ist gleich, aber die durchschnittliche Latenz beträgt 50,5 Sekunden statt 100 Sekunden.
Ein echter Datenbankserver hat mehr Ressourcen, die parallel verwendet werden können, aber das gleiche Prinzip gilt, sobald sie gesättigt sind, schadet man den Dingen nur, indem man mehr gleichzeitige Datenbankanfragen hinzufügt. Es ist tatsächlich schlimmer als das Beispiel, da Sie mit mehr Tasks mehr Taskwechsel, erhöhte Konkurrenz um Sperren und Cache, L2- und L3-Cache-Line-Konkurrenz und viele andere Probleme haben, die sowohl den Durchsatz als auch die Latenz beeinträchtigen. Dazu noch ein hoher work_mem
Diese Einstellung kann eine Abfrage auf verschiedene Weise unterstützen, diese Einstellung ist das Limit pro Planknoten für jede Verbindung , also müssen Sie bei einer großen Anzahl von Verbindungen diesen Wert sehr klein lassen, um zu vermeiden, dass der Cache geleert wird oder sogar zu Auslagerungen führt, was zu langsameren Plänen oder solchen Dingen wie dem Überlaufen von Hash-Tabellen auf die Festplatte führt.
Einige Datenbankprodukte bauen effektiv einen Verbindungspool in den Server ein, aber die PostgreSQL-Community vertritt die Position, dass sie es den Benutzern überlassen wird, dies zu verwalten, da das beste Verbindungspooling näher an der Clientsoftware erfolgt. Die meisten Pooler haben eine Möglichkeit, die Datenbankverbindungen auf eine feste Zahl zu begrenzen, während sie mehr gleichzeitige Clientanforderungen zulassen und sie nach Bedarf in die Warteschlange stellen. Das ist, was Sie wollen, und es sollte auf einer Transaktion erfolgen Grundlage, nicht pro Anweisung oder Verbindung.