Korrektheit zuerst :Ich vermute einen Fehler in Ihrer Abfrage:
LEFT JOIN historical_ohlcv ohlcv ON ohlcv.time_open >= g.start_time
AND ohlcv.time_close < g.end_time
Im Gegensatz zu meiner Antwort, auf die verwiesen wird, treten Sie in einem Zeitintervall Intervall bei :(time_open, time_close]
. Auf diese Weise werden Zeilen in der Tabelle ausgeschlossen, in denen das Intervall Bucket-Grenzen überschreitet. Es zählen nur Intervalle, die vollständig in einem einzelnen Bucket enthalten sind. Ich glaube nicht, dass das beabsichtigt ist?
Eine einfache Lösung wäre, die Bucket-Mitgliedschaft basierend auf time_open
zu entscheiden (oder time_close
) allein. Wenn Sie weiterhin mit beiden arbeiten möchten, müssen Sie genau definieren wie man mit Intervallen umgeht, die sich mit mehreren Buckets überschneiden.
Außerdem suchen Sie nach max(high)
pro Bucket, was sich von Natur aus von count(*)
unterscheidet in meiner referenzierten Antwort.
Und Ihre Buckets sind einfache Intervalle pro Stunde?
Dann können wir radikal vereinfachen. Arbeiten mit nur time_open
:
SELECT date_trunc('hour', time_open) AS hour, max(high) AS max_high
FROM historical_ohlcv
WHERE exchange_symbol = 'BINANCE'
AND symbol_id = 'ETHBTC'
AND time_open >= now() - interval '5 months' -- frame_start
AND time_open < now() -- frame_end
GROUP BY 1
ORDER BY 1;
Verwandte:
- Resample auf Zeitreihendaten
Es ist schwer, über weitere Leistungsoptimierung zu sprechen, solange die Grundlagen unklar sind. Und wir bräuchten mehr Informationen.
Sind WHERE
conditions-Variable?
Wie viele unterschiedliche Werte in exchange_symbol
und symbol_id
?
Durchschn. Zeilengröße? Was bekommen Sie für:
SELECT avg(pg_column_size(t)) FROM historical_ohlcv t TABLESAMPLE SYSTEM (0.1);
Ist die Tabelle schreibgeschützt?
Angenommen, Sie filtern immer nach exchange_symbol
und symbol_id
und Werte variabel sind, Ihre Tabelle schreibgeschützt ist oder die Selbstbereinigung mit der Schreiblast Schritt halten kann, sodass wir auf Index-Only-Scans hoffen können, sollten Sie am besten einen mehrspaltigen Index verwenden auf (exchange_symbol, symbol_id, time_open, high DESC)
um diese Abfrage zu unterstützen. Indexspalten in dieser Reihenfolge. Verwandte:
- Mehrspaltiger Index und Leistung
Je nach Datenverteilung und anderen Details ein LEFT JOIN LATERAL
Lösung könnte eine andere Option sein. Verwandte:
- So finden Sie einen Durchschnitt von Werten für Zeitintervalle in Postgres
- Optimieren Sie die GROUP BY-Abfrage, um den neuesten Datensatz pro Benutzer abzurufen
Abgesehen von all dem EXPLAIN
Sie Plan weist einige sehr auf schlechte Schätzungen :
- https://explain.depesz.com/s/E5yI
Verwenden Sie einen Strom Version von Postgres? Möglicherweise müssen Sie an Ihrer Serverkonfiguration arbeiten - oder zumindest höhere Statistikziele für relevante Spalten und aggressivere Autovacuum-Einstellungen für die große Tabelle festlegen. Verwandte:
- Halten Sie PostgreSQL davon ab, manchmal einen schlechten Abfrageplan zu wählen
- Aggressive Selbstbereinigung auf PostgreSQL