Správnost především :Mám podezření na chybu ve vašem dotazu:
LEFT JOIN historical_ohlcv ohlcv ON ohlcv.time_open >= g.start_time
AND ohlcv.time_close < g.end_time
Na rozdíl od mé odkazované odpovědi se připojujete v časovém intervalu :(time_open, time_close]
. Způsob, jakým to uděláte, vylučuje řádky v tabulce, kde interval překračuje hranice segmentu. Počítají se pouze intervaly plně obsažené v jednom segmentu. Nemyslím si, že je to zamýšleno?
Jednoduchou opravou by bylo rozhodnout o členství v segmentu na základě time_open
(nebo time_close
) sám. Pokud chcete nadále pracovat s oběma, musíte definovat přesně jak se vypořádat s intervaly překrývajícími se s více segmenty.
Také hledáte max(high)
na kbelík, což se svou povahou liší od count(*)
v mé odkazované odpovědi.
A vaše kbelíky jsou jednoduché intervaly za hodinu?
Pak můžeme radikálně zjednodušit. Práce pouze s 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;
Související:
- Převzorkování dat časové řady
Je těžké mluvit o další optimalizaci výkonu, zatímco základy jsou nejasné. A potřebovali bychom více informací.
Jsou WHERE
proměnná podmínek?
Kolik různých hodnot v exchange_symbol
a symbol_id
?
Prům. velikost řádku? Za co získáte:
SELECT avg(pg_column_size(t)) FROM historical_ohlcv t TABLESAMPLE SYSTEM (0.1);
Je tabulka pouze pro čtení?
Za předpokladu, že vždy filtrujete podle exchange_symbol
a symbol_id
a hodnoty jsou proměnlivé, vaše tabulka je pouze pro čtení nebo autovakuum může držet krok se zatížením zápisu, takže můžeme doufat v skenování pouze s indexem, nejlépe byste měli vícesloupcový index na (exchange_symbol, symbol_id, time_open, high DESC)
na podporu tohoto dotazu. Indexujte sloupce v tomto pořadí. Související:
- Vícesloupcový index a výkon
V závislosti na distribuci dat a dalších podrobnostech LEFT JOIN LATERAL
řešením může být jiná možnost. Související:
- Jak najít průměr hodnot pro časové intervaly v postgres
- Optimalizujte dotaz GROUP BY pro získání nejnovějšího záznamu na uživatele
Kromě toho všeho EXPLAIN
plán vykazuje některévelmi špatné odhady :
- https://explain.depesz.com/s/E5yI
Používáte aktuální verze Postgresu? Možná budete muset zapracovat na konfiguraci serveru – nebo alespoň nastavit vyšší statistické cíle pro relevantní sloupce a agresivnější nastavení autovakuování pro velký stůl. Související:
- Zabraňte PostgreSQL, aby někdy zvolil špatný plán dotazů
- Agresivní automatické vakuování na PostgreSQL