Prima la correttezza :Sospetto un bug nella tua query:
LEFT JOIN historical_ohlcv ohlcv ON ohlcv.time_open >= g.start_time
AND ohlcv.time_close < g.end_time
A differenza della mia risposta di riferimento, ti unisci a un intervallo di tempo :(time_open, time_close]
. Il modo in cui lo fai esclude le righe nella tabella in cui l'intervallo attraversa i bordi del bucket. Solo gli intervalli completamente contenuti in un singolo bucket. Non credo sia previsto?
Una semplice soluzione sarebbe decidere l'appartenenza al bucket in base a time_open
(o time_close
) solo. Se vuoi continuare a lavorare con entrambi, devi definire esattamente come gestire gli intervalli che si sovrappongono a più bucket.
Inoltre, stai cercando max(high)
per bucket, che è di natura diversa da count(*)
nella mia risposta di riferimento.
E i tuoi secchi sono semplici intervalli all'ora?
Allora possiamo semplificare radicalmente. Lavorare solo con 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;
Correlati:
- Ricampiona i dati delle serie temporali
È difficile parlare di un'ulteriore ottimizzazione delle prestazioni mentre le basi non sono chiare. E avremmo bisogno di più informazioni.
Sono WHERE
condizioni variabili?
Quanti valori distinti in exchange_symbol
e symbol_id
?
Media dimensione della riga? Cosa ottieni per:
SELECT avg(pg_column_size(t)) FROM historical_ohlcv t TABLESAMPLE SYSTEM (0.1);
La tabella è di sola lettura?
Supponendo che filtri sempre su exchange_symbol
e symbol_id
e i valori sono variabili, la tabella è di sola lettura o l'autovacuum può tenere il passo con il carico di scrittura in modo da poter sperare in scansioni solo indice, è meglio avere un indice multicolonna su (exchange_symbol, symbol_id, time_open, high DESC)
per supportare questa domanda. Colonne dell'indice in questo ordine. Correlati:
- Indice multicolonna e performance
A seconda della distribuzione dei dati e di altri dettagli, un LEFT JOIN LATERAL
la soluzione potrebbe essere un'altra opzione. Correlati:
- Come trovare una media dei valori per gli intervalli di tempo in postgres
- Ottimizza la query GROUP BY per recuperare l'ultimo record per utente
A parte tutto questo, tu EXPLAIN
plan mostra alcuni molto stime sbagliate :
- https://explain.depesz.com/s/E5yI
Stai usando una corrente versione di Postgres? Potrebbe essere necessario lavorare sulla configurazione del server o almeno impostare obiettivi statistici più elevati su colonne pertinenti e impostazioni di autovacuum più aggressive per il tavolo grande. Correlati:
- Impedisci a PostgreSQL di scegliere a volte un piano di query errato
- Autovacuum aggressivo su PostgreSQL