it-swarm.com.de

Postgres 9.0 vs Postgres 10 & 11 Leistung

Wir möchten unsere Datenbanken vom Webhosting-Anbieter (Postgres 9.0) auf unseren lokalen Netzwerkserver verschieben (sowohl Postgres 10 als auch die neueste Version 11). Unser Computer ist ein Windows Server, ein schneller XEON-Computer mit 16 GB RAM, nur für die Datenbank.

Aber selbst nachdem wir default_statistics_targer = 4000 ausgelöst und nach Statistiken analysiert haben, haben wir Probleme, viele Ansichten auszuführen, die zuvor sehr schnell funktionierten. Der Webhosting-Provider-Server wurde anscheinend optimiert und unsere Ausführungspläne sind wahrscheinlich aus irgendeinem Grund seltsam.

Unsere Postgres ist Lagerinstallationskonfiguration.

Die vereinfachte Beispielabfrage ist unten (die größte Tabelle ist "Dale Table", die mehrere Millionen Datensätze groß ist (es handelt sich um eine Bindungstabelle mit Fremdschlüsseln). Andere Tabellen sind viel kleiner, Zehntausende von Datensätzen (das System wird vakuumanalytisch analysiert und neu installiert).

EXPLAIN ANALYZE
SELECT REKLAMACNY_LIST.ID REKLAMACNY_LIST_ID
FROM REKLAMACNY_LIST
WHERE REKLAMACNY_LIST.VALIDTO IS NULL
  AND
    ( SELECT NOT tr.typ_odstupenia::boolean
     AND sr.konecny_stav::boolean
     FROM dale d1
     CROSS JOIN typ_reklamacie tr
     CROSS JOIN dale d2
     CROSS JOIN stav_reklamacie sr
     WHERE TRUE
       AND d1.fk7 = reklamacny_list.id
       AND d2.fk7 = reklamacny_list.id
       AND d1.fk1 = tr.id
       AND d2.fk3 = sr.id
       AND sr.validto IS NULL
       AND tr.validto IS NULL
       AND d1.validto IS NULL
       AND d2.validto IS NULL )
ORDER BY reklamacny_list_id DESC
LIMIT 100

Erklären Sie die Analyse für unseren Test-Postgres-11-Server

"Limit  (cost=0.29..18432.84 rows=100 width=4) (actual time=11804.484..331036.595 rows=91 loops=1)"
"  ->  Index Scan Backward using reklamacny_list_pk on reklamacny_list  (cost=0.29..2578713.84 rows=13990 width=4) (actual time=11804.482..331036.524 rows=91 loops=1)"
"        Index Cond: (id > 0)"
"        Filter: ((validto IS NULL) AND (SubPlan 1))"
"        Rows Removed by Filter: 29199"
"        SubPlan 1"
"          ->  Hash Join  (cost=5.30..87.57 rows=250 width=1) (actual time=5.246..11.824 rows=1 loops=27981)"
"                Hash Cond: (d2.fk3 = sr.id)"
"                ->  Merge Join  (cost=1.85..80.76 rows=324 width=9) (actual time=5.222..11.806 rows=6 loops=27981)"
"                      Merge Cond: (d1.fk1 = tr.id)"
"                      ->  Nested Loop  (cost=0.71..25556.34 rows=324 width=8) (actual time=5.211..11.794 rows=6 loops=27981)"
"                            ->  Index Scan using dale_idx_fk1 on dale d1  (cost=0.29..25510.95 rows=18 width=4) (actual time=5.195..11.772 rows=1 loops=27981)"
"                                  Filter: (fk7 = reklamacny_list.id)"
"                                  Rows Removed by Filter: 28432"
"                            ->  Materialize  (cost=0.42..41.38 rows=18 width=4) (actual time=0.011..0.015 rows=6 loops=27890)"
"                                  ->  Index Scan using dale_fk7_idx on dale d2  (cost=0.42..41.29 rows=18 width=4) (actual time=0.007..0.010 rows=6 loops=27890)"
"                                        Index Cond: (fk7 = reklamacny_list.id)"
"                      ->  Sort  (cost=1.14..1.15 rows=6 width=9) (actual time=0.009..0.009 rows=1 loops=27890)"
"                            Sort Key: tr.id"
"                            Sort Method: quicksort  Memory: 25kB"
"                            ->  Seq Scan on typ_reklamacie tr  (cost=0.00..1.06 rows=6 width=9) (actual time=0.002..0.004 rows=6 loops=27890)"
"                                  Filter: (validto IS NULL)"
"                ->  Hash  (cost=2.74..2.74 rows=57 width=9) (actual time=0.046..0.047 rows=57 loops=1)"
"                      Buckets: 1024  Batches: 1  Memory Usage: 11kB"
"                      ->  Seq Scan on stav_reklamacie sr  (cost=0.00..2.74 rows=57 width=9) (actual time=0.012..0.030 rows=57 loops=1)"
"                            Filter: (validto IS NULL)"
"                            Rows Removed by Filter: 17"
"Planning Time: 10.174 ms"
"Execution Time: 331036.893 ms"

die Ausführung dauert ewig im Vergleich zum unmittelbaren Ergebnis unserer Test-Postgres 10.0

"Limit  (cost=0.29..163635.75 rows=100 width=4) (actual time=24.199..925.691 rows=70 loops=1)"
"  ->  Index Scan Backward using reklamacny_list_pk on reklamacny_list  (cost=0.29..21326610.37 rows=13033 width=4) (actual time=24.195..925.660 rows=70 loops=1)"
"        Index Cond: (id > 0)"
"        Filter: ((validto IS NULL) AND (SubPlan 1))"
"        Rows Removed by Filter: 27218"
"        SubPlan 1"
"          ->  Nested Loop  (cost=4.22..781.03 rows=1293 width=1) (actual time=0.018..0.034 rows=1 loops=26066)"
"                ->  Hash Join  (cost=3.80..377.12 rows=76 width=5) (actual time=0.005..0.005 rows=1 loops=26066)"
"                      Hash Cond: (d2.fk3 = sr.id)"
"                      ->  Index Scan using dale_fk7_idx on dale d2  (cost=0.42..372.47 rows=100 width=4) (actual time=0.002..0.004 rows=5 loops=26066)"
"                            Index Cond: (fk7 = reklamacny_list.id)"
"                      ->  Hash  (cost=2.71..2.71 rows=54 width=9) (actual time=0.049..0.049 rows=54 loops=1)"
"                            Buckets: 1024  Batches: 1  Memory Usage: 11kB"
"                            ->  Seq Scan on stav_reklamacie sr  (cost=0.00..2.71 rows=54 width=9) (actual time=0.016..0.032 rows=54 loops=1)"
"                                  Filter: (validto IS NULL)"
"                                  Rows Removed by Filter: 17"
"                ->  Materialize  (cost=0.42..374.87 rows=17 width=24) (actual time=0.013..0.027 rows=1 loops=25987)"
"                      ->  Nested Loop  (cost=0.42..374.78 rows=17 width=24) (actual time=0.010..0.024 rows=1 loops=25987)"
"                            Join Filter: (d1.fk1 = tr.id)"
"                            Rows Removed by Join Filter: 32"
"                            ->  Seq Scan on typ_reklamacie tr  (cost=0.00..1.06 rows=1 width=28) (actual time=0.001..0.002 rows=6 loops=25987)"
"                                  Filter: (validto IS NULL)"
"                            ->  Index Scan using dale_fk7_idx on dale d1  (cost=0.42..372.47 rows=100 width=4) (actual time=0.002..0.003 rows=5 loops=155922)"
"                                  Index Cond: (fk7 = reklamacny_list.id)"
"Planning time: 8.460 ms"
"Execution time: 925.870 ms"

Dies ist nur ein Beispiel. Aber fast jede Abfrage ist auf 11 einfach um ein Vielfaches langsamer, und selbst Dinge, die auch auf 10 ewig dauern, werden sofort von den Webanbietern postgres 9.0 zurückgegeben (die auch Hunderte verschiedener Datenbanken hosten).

Haben Sie einen Punkt, an dem es sich zu untersuchen lohnt?

Kann das Anpassen einiger Speicherparameter helfen? (Der Server hat 16 GB nur für Postgres und Betriebssystem, es werden ungefähr 50 Benutzer eine Verbindung herstellen.) Das Erhöhen von default_statisticts_target = 10000 hat viel geholfen, aber selbst dann.

Eine andere Version der Anfrage mit Coalesce ansonsten gleich

EXPLAIN ANALYZE
SELECT REKLAMACNY_LIST.ID REKLAMACNY_LIST_ID
FROM REKLAMACNY_LIST
WHERE REKLAMACNY_LIST.VALIDTO IS NULL
  AND REKLAMACNY_LIST.ID > 0
  AND ((
          ( SELECT (NOT COALESCE(tr.typ_odstupenia, 'False')::boolean)
           AND COALESCE(sr.konecny_stav, 'False'):: boolean
           FROM dale d1
           CROSS JOIN typ_reklamacie tr
           CROSS JOIN dale d2
           CROSS JOIN stav_reklamacie sr
           WHERE TRUE
             AND d1.fk7 = reklamacny_list.id
             AND d2.fk7 = reklamacny_list.id
             AND d1.fk1 = tr.id
             AND d2.fk3 = sr.id
             AND sr.validto IS NULL
             AND tr.validto IS NULL
             AND d1.validto IS NULL
             AND d2.validto IS NULL )))
ORDER BY reklamacny_list_id DESC
LIMIT 100

Bei Postgres 11 springt es auf 10 Sekunden (großer Unterschied zur vorherigen Version der Anfrage ohne Zusammenführung)

"Limit  (cost=0.29..18432.84 rows=100 width=4) (actual time=447.853..10695.583 rows=100 loops=1)"
"  ->  Index Scan Backward using reklamacny_list_pk on reklamacny_list  (cost=0.29..2578713.84 rows=13990 width=4) (actual time=447.851..10695.495 rows=100 loops=1)"
"        Index Cond: (id > 0)"
"        Filter: ((validto IS NULL) AND (SubPlan 1))"
"        Rows Removed by Filter: 687"
"        SubPlan 1"
"          ->  Hash Join  (cost=5.30..87.57 rows=250 width=1) (actual time=11.436..14.102 rows=1 loops=758)"
"                Hash Cond: (d2.fk3 = sr.id)"
"                ->  Merge Join  (cost=1.85..80.76 rows=324 width=9) (actual time=11.407..14.076 rows=5 loops=758)"
"                      Merge Cond: (d1.fk1 = tr.id)"
"                      ->  Nested Loop  (cost=0.71..25556.34 rows=324 width=8) (actual time=11.389..14.056 rows=5 loops=758)"
"                            ->  Index Scan using dale_idx_fk1 on dale d1  (cost=0.29..25510.95 rows=18 width=4) (actual time=11.361..14.023 rows=1 loops=758)"
"                                  Filter: (fk7 = reklamacny_list.id)"
"                                  Rows Removed by Filter: 28432"
"                            ->  Materialize  (cost=0.42..41.38 rows=18 width=4) (actual time=0.017..0.021 rows=5 loops=754)"
"                                  ->  Index Scan using dale_fk7_idx on dale d2  (cost=0.42..41.29 rows=18 width=4) (actual time=0.009..0.012 rows=5 loops=754)"
"                                        Index Cond: (fk7 = reklamacny_list.id)"
"                      ->  Sort  (cost=1.14..1.15 rows=6 width=9) (actual time=0.015..0.015 rows=2 loops=754)"
"                            Sort Key: tr.id"
"                            Sort Method: quicksort  Memory: 25kB"
"                            ->  Seq Scan on typ_reklamacie tr  (cost=0.00..1.06 rows=6 width=9) (actual time=0.003..0.006 rows=6 loops=754)"
"                                  Filter: (validto IS NULL)"
"                ->  Hash  (cost=2.74..2.74 rows=57 width=9) (actual time=0.092..0.092 rows=57 loops=1)"
"                      Buckets: 1024  Batches: 1  Memory Usage: 11kB"
"                      ->  Seq Scan on stav_reklamacie sr  (cost=0.00..2.74 rows=57 width=9) (actual time=0.032..0.068 rows=57 loops=1)"
"                            Filter: (validto IS NULL)"
"                            Rows Removed by Filter: 17"
"Planning Time: 1.556 ms"
"Execution Time: 10695.752 ms"

auf

postgres 10

"Limit  (cost=0.29..163635.75 rows=100 width=4) (actual time=1.958..20.024 rows=100 loops=1)"
"  ->  Index Scan Backward using reklamacny_list_pk on reklamacny_list  (cost=0.29..21326610.37 rows=13033 width=4) (actual time=1.957..20.011 rows=100 loops=1)"
"        Index Cond: (id > 0)"
"        Filter: ((validto IS NULL) AND (SubPlan 1))"
"        Rows Removed by Filter: 572"
"        SubPlan 1"
"          ->  Nested Loop  (cost=4.22..781.03 rows=1293 width=1) (actual time=0.017..0.031 rows=1 loops=609)"
"                ->  Hash Join  (cost=3.80..377.12 rows=76 width=5) (actual time=0.004..0.004 rows=1 loops=609)"
"                      Hash Cond: (d2.fk3 = sr.id)"
"                      ->  Index Scan using dale_fk7_idx on dale d2  (cost=0.42..372.47 rows=100 width=4) (actual time=0.002..0.003 rows=5 loops=609)"
"                            Index Cond: (fk7 = reklamacny_list.id)"
"                      ->  Hash  (cost=2.71..2.71 rows=54 width=9) (actual time=0.037..0.037 rows=54 loops=1)"
"                            Buckets: 1024  Batches: 1  Memory Usage: 11kB"
"                            ->  Seq Scan on stav_reklamacie sr  (cost=0.00..2.71 rows=54 width=9) (actual time=0.009..0.023 rows=54 loops=1)"
"                                  Filter: (validto IS NULL)"
"                                  Rows Removed by Filter: 17"
"                ->  Materialize  (cost=0.42..374.87 rows=17 width=24) (actual time=0.013..0.025 rows=1 loops=604)"
"                      ->  Nested Loop  (cost=0.42..374.78 rows=17 width=24) (actual time=0.010..0.022 rows=1 loops=604)"
"                            Join Filter: (d1.fk1 = tr.id)"
"                            Rows Removed by Join Filter: 31"
"                            ->  Seq Scan on typ_reklamacie tr  (cost=0.00..1.06 rows=1 width=28) (actual time=0.001..0.002 rows=6 loops=604)"
"                                  Filter: (validto IS NULL)"
"                            ->  Index Scan using dale_fk7_idx on dale d1  (cost=0.42..372.47 rows=100 width=4) (actual time=0.002..0.003 rows=5 loops=3624)"
"                                  Index Cond: (fk7 = reklamacny_list.id)"
"Planning time: 1.418 ms"
"Execution time: 20.193 ms"

Ich füge vollständige Protokolle in der Zip-Datei hinzu (einschließlich der Konfiguration postgres.conf). Es scheint, als würde das Erhöhen des Standardstatistikziels helfen, jedoch nur bei sehr hohen Werten.
https://www.dropbox.com/s/7m3wy9nkapqitca/SpeedTest.zip?dl=

6
Martin Ritchie

Die Standardkonfiguration postgresql.conf Gilt nur für Datenbanken mit geringem Platzbedarf und ist langsam, wenn Ihre Datenbank groß ist und mithilfe komplizierter Verknüpfungen abgefragt wird.

Ich habe aus Ihrer postgresql10-Konfigurationsdatei gesehen, dass Ihr gemeinsam genutzter Speicher nur auf 128MB Eingestellt ist (auch viele andere Einstellungen sind sehr klein). Sie müssen dies neu konfigurieren.

Das Optimieren des PostgreSQL-Servers ist ein großes Thema, und verschiedene Arten von Hardware würden auch unterschiedliche Einstellungen erfordern, was auch mit Versuch und Irrtum einhergeht und die Einstellungen/Konfiguration kontinuierlich verbessert.

Ich kann hier nicht den ganzen Topie diskutieren, ich kann nur die abgestimmten Einstellungen angeben, die ich früher verwendet habe.

Ziel

  • Verwenden Sie nicht mehr als 4 GB Speicher auf meinem Server (da mein Server nicht für die Ausführung von PostgreSQL DB vorgesehen ist).
  • Server hat> 8 Kerne
max_connections : 800
shared_buffers : 1536MB
work_mem : 24MB
maintenance_work_mem : 480MB
vacuum_cost_delay : 20ms
synchronous_commit : local
wal_buffers : 8MB
max_wal_size : 1536GB
checkpoint_completion_target : 0.9
effective_cache_size : 4GB
deadlock_timeout : 3s
log_min_duration_statement : 5000
log_error_verbosity : verbose
log_autovacuum_min_duration : 10000
log_lock_waits : on
5
user170807

psql 10: Puffer: geteilter Treffer = 4.439.193
Psql 09: Puffer: geteilter Treffer = ____ 7.493 read = 686

https://www.postgresql.org/docs/11/sql-explain.html

Fügen Sie Informationen zur Puffernutzung hinzu. Geben Sie insbesondere die Anzahl der gemeinsam genutzten Blöcke an, die getroffen, gelesen, verschmutzt und geschrieben wurden, die Anzahl der lokalen Blöcke, die getroffen, gelesen, verschmutzt und geschrieben wurden, und die Anzahl der gelesenen und geschriebenen temporären Blöcke. Ein Treffer bedeutet, dass ein Lesevorgang vermieden wurde, da der Block bei Bedarf bereits im Cache gefunden wurde. Freigegebene Blöcke enthalten Daten aus regulären Tabellen und Indizes. lokale Blöcke enthalten Daten aus temporären Tabellen und Indizes; Während temporäre Blöcke kurzfristige Arbeitsdaten enthalten, die in Sortierungen, Hashes, Materialise-Plan-Knoten und ähnlichen Fällen verwendet werden. Die Anzahl der verschmutzten Blöcke gibt die Anzahl der zuvor unveränderten Blöcke an, die durch diese Abfrage geändert wurden. Die Anzahl der geschriebenen Blöcke gibt die Anzahl der zuvor verschmutzten Blöcke an, die von diesem Backend während der Abfrageverarbeitung aus dem Cache entfernt wurden. Die Anzahl der Blöcke, die für einen Knoten der oberen Ebene angezeigt werden, umfasst diejenigen, die von allen untergeordneten Knoten verwendet werden. Im Textformat werden nur Werte ungleich Null gedruckt. Dieser Parameter darf nur verwendet werden, wenn auch ANALYZE aktiviert ist. Der Standardwert ist FALSE.

mit DB auf dem P09 stimmt etwas nicht. Auf dem P10 gibt es ~ 8000 Pufferbeteiligungen. Auf dem P10 gibt es 4M Puffertreffer

wenn sich das auf demselben Dataset befindet, müssen viele leere/gelöschte Zeilen in den Datenbanken vorhanden sein.

wenn dies der Fall ist, sollte Vakuum helfen.


die Ausführungspläne sind sehr unterschiedlich. Die Schätzung der Anzahl der beteiligten Zeilen ist unterschiedlich. Eine aktualisierte Statistik für bestimmte Spalten kann hilfreich sein

https://www.citusdata.com/blog/2018/03/06/postgres-planner-and-its-usage-of-statistics/


psql 09 plan hat keinen separaten sortierteil. Vielleicht sind die Indizes nicht gleich. psql 09 erhält möglicherweise bereits das Datum in der richtigen Reihenfolge ....

2
user1817599