PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Postgres-Abfragen in der Produktion führen zu ungewöhnlich hohen Lese-E/A-Vorgängen auf der Festplatte

Diese Abfrage erzeugte keine Platten-I/O – alle Blöcke werden aus gemeinsam genutzten Puffern gelesen. Da die Abfrage jedoch 73424 Blöcke (ca. 574 MB) liest, erzeugt sie eine erhebliche E/A-Last, wenn die Tabelle nicht zwischengespeichert wird.

Aber es gibt zwei Dinge, die verbessert werden können.

  • Sie haben verlustbehaftete Blockübereinstimmungen im Heap-Scan. Das bedeutet, dass work_mem nicht groß genug ist, um eine Bitmap mit einem Bit pro Tabellenzeile aufzunehmen, und 26592 Bits bilden stattdessen einen Tabellenblock ab. Alle Zeilen müssen erneut überprüft werden, und 86733 Zeilen werden verworfen, von denen die meisten falsch positive Ergebnisse aus den verlustbehafteten Blockübereinstimmungen sind.

    Wenn Sie work_mem erhöhen , passt eine Bitmap mit einem Bit pro Tabellenzeile in den Speicher, und diese Zahl wird kleiner, wodurch die Arbeit während des Heap-Scans reduziert wird.

  • 190108 Zeilen werden verworfen, da sie nicht der zusätzlichen Filterbedingung im Bitmap-Heap-Scan entsprechen. Hier wird wahrscheinlich die meiste Zeit verbracht. Wenn Sie diesen Betrag reduzieren können, gewinnen Sie.

    Die idealen Indizes für diese Abfrage wären:

    CREATE INDEX ON map_listing(transaction_type, la);
    CREATE INDEX ON map_listing(transaction_type, lo);
    

    Wenn transaction_type ist nicht sehr selektiv (d.h. die meisten Zeilen haben den Wert Sale ), können Sie diese Spalte weglassen.

BEARBEITEN:

Untersuchung von vmstat und iostat zeigt, dass sowohl die CPU als auch das I/O-Subsystem unter massiver Überlastung leiden:Alle CPU-Ressourcen werden für I/O-Wartezeit und VM-Steal-Zeit verbraucht. Sie benötigen ein besseres E/A-System und ein Hostsystem mit mehr freien CPU-Ressourcen. Erhöhen des Arbeitsspeichers kann das E/A-Problem lindern, aber nur für die Lesevorgänge auf der Festplatte.