Neben dem Speichern des Overheads von connect & trennen Sie, wo dies sonst bei jeder Anfrage getan wird, kann eine Verbindung Pooler eine große Anzahl von Client-Verbindungen auf eine kleine Anzahl von tatsächlichen Datenbankverbindungen Trichter. In PostgreSQL liegt die optimale Anzahl aktiver Datenbankverbindungen normalerweise irgendwo ((2 * core_count) + effective_spindle_count). Über dieser Zahl werden sowohl der Durchsatz als auch die Latenz schlechter.
Manchmal werden Leute sagen "Ich möchte 2000 Benutzer mit schneller Reaktionszeit unterstützen." Es ist ziemlich sicher, dass, wenn Sie versuchen, das mit 2000 tatsächlichen Datenbankverbindungen zu tun, Leistung wird schrecklich sein. Wenn Sie über einen Computer mit vier Quad-Core-Prozessoren verfügen und der aktive Datensatz vollständig zwischengespeichert ist, können Sie für diese 2000 Benutzer eine wesentlich bessere Leistung erzielen, indem Sie die Anforderungen über etwa 35 Datenbankverbindungen verwalten.
Um zu verstehen, warum das stimmt, sollte dieses Gedankenexperiment helfen. Stellen Sie sich einen hypothetischen Datenbankserver mit nur einer Ressource vor - einen einzelnen Kern. Dieser Kern wird gleichmäßig unter allen gleichzeitigen Anfragen ohne Overhead aufgeteilt. Nehmen wir an, dass 100 Anfragen alle gleichzeitig eintreffen, wobei jede eine Sekunde CPU-Zeit benötigt. Der Kern arbeitet auf allen von ihnen, zerteilt unter ihnen, bis sie alle 100 Sekunden später beenden. Betrachten Sie nun, was passiert, wenn Sie einen Verbindungspool vorgeben, der 100 Client-Verbindungen akzeptiert, aber jeweils nur eine Anfrage an den Datenbankserver stellt und alle Anfragen, die während der Verbindung in einer Warteschlange eingehen, anfordert. Wenn nun 100 Anfragen zur selben Zeit eintreffen, erhält ein Client eine Antwort in 1 Sekunde; ein anderer erhält eine Antwort in 2 Sekunden, und der letzte Client erhält eine Antwort in 100 Sekunden. Niemand musste länger warten, um eine Antwort zu erhalten, der Durchsatz ist der gleiche, aber die durchschnittliche Latenz beträgt 50,5 Sekunden statt 100 Sekunden.
Ein realer Datenbankserver hat mehr Ressourcen, die parallel verwendet werden können, aber das gleiche Prinzip gilt, sobald sie gesättigt sind, verletzen Sie nur die Dinge, indem Sie mehr gleichzeitige Datenbankanforderungen hinzufügen. Es ist tatsächlich schlimmer als das Beispiel, denn mit mehr Aufgaben haben Sie mehr Task-Switches, erhöhte Konflikte für Sperren und Cache, L2- und L3-Cache-Zeilenkonflikte und viele andere Probleme, die sowohl den Durchsatz als auch die Latenz verringern. Obendrein, während eine hohe work_mem
Einstellung kann eine Abfrage auf eine Reihe von Möglichkeiten helfen, ist diese Einstellung das Limit pro Plan Knoten für jede Verbindung, so mit einer großen Anzahl von Verbindungen müssen Sie diese sehr klein zu vermeiden Leeren des Caches oder sogar das Auslagern, was zu langsameren Plänen oder zu Hash-Tabellen führt, die auf die Festplatte ausgelaufen sind.
Einige Datenbankprodukte bauen effektiv einen Verbindungspool in den Server auf, aber die PostgreSQL-Gemeinschaft hat die Position eingenommen, dass das beste Verbindungs-Pooling der Client-Software überlassen wird. Die meisten Pooler haben eine Möglichkeit, die Datenbankverbindungen auf eine feste Nummer zu begrenzen, während sie mehr gleichzeitige Clientanforderungen zulassen und sie in der Warteschlange anordnen. Dies ist, was Sie wollen, und es sollte auf einer Transaktion Basis, nicht pro Anweisung oder Verbindung erfolgen.
Es besteht auch die Möglichkeit, dass Ihr Datenbankmodell nicht mit den Abfragen übereinstimmt, die Sie auslösen. Normalerweise ist der Netzwerk-Overhead im Vergleich zu der Arbeit, die zum Abrufen von Datenblöcken von der Festplatte benötigt wird, ebenfalls sehr klein: Dies kostet nicht die Leistung, sondern nur die Latenz. (außer vielleicht für den Fall sehr häufiger Verbindungen/Disconnect) – wildplasser