Meine Abfragen werden sehr langsam, wenn ich eine limit 1
hinzufügen.PostgreSQL Abfrage sehr langsam mit Limit 1
Ich habe eine Tabelle object_values
mit timestamped Werte für Objekte:
timestamp | objectID | value
--------------------------------
2014-01-27| 234 | ksghdf
pro Objekt, das ich den letzten Wert erhalten möchten:
SELECT * FROM object_values WHERE (objectID = 53708) ORDER BY timestamp DESC LIMIT 1;
(I annulliert die Abfrage nach mehr als 10 Minuten)
Diese Abfrage ist sehr langsam, wenn für eine gegebene objectID keine Werte vorhanden sind (sie ist schnell, wenn Ergebnisse vorhanden sind). Wenn ich die Grenze entfernen Sie es mich fast sofort sagt, dass es keine Ergebnisse:
SELECT * FROM object_values WHERE (objectID = 53708) ORDER BY timestamp DESC;
...
Time: 0.463 ms
Ein erklären, zeigt mir, dass die Abfrage ohne Limit den Index verwendet, wo, wie die Abfrage mit limit 1
nicht die Verwendung des Index machen :
langsam query:
explain SELECT * FROM object_values WHERE (objectID = 53708) ORDER BY timestamp DESC limit 1;
QUERY PLAN`
----------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.00..2350.44 rows=1 width=126)
-> Index Scan Backward using object_values_timestamp on object_values (cost=0.00..3995743.59 rows=1700 width=126)
Filter: (objectID = 53708)`
Schnelle Abfrage:
explain SELECT * FROM object_values WHERE (objectID = 53708) ORDER BY timestamp DESC;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------
Sort (cost=6540.86..6545.11 rows=1700 width=126)
Sort Key: timestamp
-> Index Scan using object_values_objectID on working_hours_t (cost=0.00..6449.65 rows=1700 width=126)
Index Cond: (objectID = 53708)
Die Tabelle enthält 44.884.559 Zeilen und 66.762 eindeutige ObjectIDs.
Ich habe separate Indizes für beide Felder: timestamp
und objectID
.
Ich habe eine vacuum analyze
auf dem Tisch gemacht und ich habe die Tabelle neu indiziert.
Zusätzlich wird die langsame Abfrage wird schnell, wenn ich die Grenze bis 3 oder höher:
explain SELECT * FROM object_values WHERE (objectID = 53708) ORDER BY timestamp DESC limit 3;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Limit (cost=6471.62..6471.63 rows=3 width=126)
-> Sort (cost=6471.62..6475.87 rows=1700 width=126)
Sort Key: timestamp
-> Index Scan using object_values_objectID on object_values (cost=0.00..6449.65 rows=1700 width=126)
Index Cond: (objectID = 53708)
Im Allgemeinen Ich nehme an, es hat mit den Planern machen falsche Annahmen über die exectution Kosten und damit wählt für eine zu tun langsamer Ausführungsplan.
Ist das der wahre Grund? Gibt es dafür eine Lösung?
Für den 'Limit 1' Fall meinst du Table Scan? Sie haben index scan geschrieben – harmic
@harmic: OP hat einen Index-Scan dort ... nicht unbedingt von der ganzen Tabelle, aber sicherlich von viel mehr davon als was PG dachte. –
Sie haben Recht! Ich habe nur den OP-Text gelesen, in dem er gesagt hat, dass er den Index nicht benutzt. Aber es wählt den Timestamp-Index aus; Seltsame Wahl – harmic