Ich brauche einige Tipps zum Optimieren von Abfragen aus großen Tabellen.Optimieren der PostgreSQL-Abfrage mit mehreren Joins, Order by und Small Limit
In diesem Beispiel habe ich 5 Tische:
Brands
- id_brand
- b_name
Products
- id_product
- p_name
- ean
...
- fk_brand
Prod_attributes
- id_prod_att
- size_basic
...
- fk_product
Stores
- id_store
- s_name
...
Stocks
- id_stock
- stock_amount
- fk_prod_att
- fk_store
ich eine Abfrage mit geordneten Liste von Aktien muß, begrenzt, so ist dies der allgemeine Ansatz, den ich verwenden:
SELECT stores.s_name, stocks.stock_amount, prod_attributes.size_basic,
products.p_name, products.ean, brands.b_name
FROM (stocks
INNER JOIN stores
ON stocks.fk_store = stores.id_store)
INNER JOIN (prod_attributes
INNER JOIN (products
INNER JOIN brands
ON products.fk_brand = brands.id_brand)
ON prod_attributes.fk_product = products.id_product)
ON stocks.fk_prod_att = prod_attributes.id_prod_att
ORDER BY s_name, p_name, size_basic
LIMIT 25 OFFSET 0
Das funktioniert schnell auf kleinen Tabellen, aber wenn die Tabellen wachsen, wird die Abfrage sehr teuer. Mit 3,5M Zeilen in Stocks, 300K in Prod_attributes, 25K Produkten wird es in über 8800ms ausgeführt, was für mich nicht akzeptabel ist.
Alle herkömmlichen Schlüssel haben Indizes und DB wurde kürzlich vakuumanalysiert.
Ich weiß, dass das Problem im ORDER BY-Teil liegt, deshalb verwendet die Abfrage keine Indizes und führt sequenzielle Scans durch. Wenn ich die Reihenfolge lösche, ist die Abfrage sehr schnell.
Für die Lösung dieses Problems weiß ich, dass ich ORDER BY entfernen kann, aber es ist keine machbare Option für mich. Eine De-Normalisierung der DB oder Materialized View könnte hier ebenfalls hilfreich sein - auch dies möchte ich nach Möglichkeit vermeiden.
Was kann ich noch tun, um diese Anfrage zu beschleunigen?
ANALYZE ERKLÄREN:
- langsam mit Auftrag von: http://explain.depesz.com/s/AHO
- schnell ohne Auftrag von: http://explain.depesz.com/s/NRxr
Haben Sie einen Index für die Reihenfolge nach Spalten? –
Hallo, ja. Ich habe die Indizes für die Reihenfolge nach Spalten als solche hinzugefügt: CREATE INDEX i_p_name ON Produkte VERWENDUNG btree (p_name); Ich fügte sie als separate Indizes - 1 für jede Reihenfolge von Feld. ASC-Reihenfolge und NULLEN LETZT. Nach der erneuten Ausführung der Abfrage hat sich nichts im Plan geändert. – Lucius
Haben Sie nach dem Erstellen von Indizes eine Analyse ausgeführt? –