Najpierw poprawność :Podejrzewam błąd w Twoim zapytaniu:
LEFT JOIN historical_ohlcv ohlcv ON ohlcv.time_open >= g.start_time
AND ohlcv.time_close < g.end_time
W przeciwieństwie do odpowiedzi, o której mowa, dołączasz w interwale :(time_open, time_close]
. Sposób, w jaki to zrobisz, wyklucza wiersze w tabeli, w których interwał przekracza granice segmentów. Liczą się tylko interwały w pełni zawarte w jednym zasobniku. Nie sądzę, żeby to było zamierzone?
Prostą poprawką byłoby podjęcie decyzji o członkostwie w zasobniku na podstawie time_open
(lub time_close
) sam. Jeśli chcesz dalej pracować z obydwoma, musisz dokładnie zdefiniować jak radzić sobie z interwałami nakładającymi się na wiele wiader.
Ponadto szukasz max(high)
na wiadro, co ma inny charakter niż count(*)
w mojej odpowiedzi.
A Twoje wiadra to proste interwały na godzinę?
Wtedy możemy radykalnie uprościć. Praca tylko z 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;
Powiązane:
- Ponowne próbkowanie danych szeregów czasowych
Trudno mówić o dalszej optymalizacji wydajności, gdy podstawy są niejasne. Potrzebowalibyśmy więcej informacji.
Czy WHERE
? zmienna warunków?
Ile różnych wartości w exchange_symbol
i symbol_id
?
Śr. rozmiar wiersza? Za co otrzymujesz:
SELECT avg(pg_column_size(t)) FROM historical_ohlcv t TABLESAMPLE SYSTEM (0.1);
Czy tabela jest tylko do odczytu?
Zakładając, że zawsze filtrujesz według exchange_symbol
i symbol_id
a wartości są zmienne, twoja tabela jest tylko do odczytu lub autovacuum może nadążyć za obciążeniem zapisu, więc możemy mieć nadzieję na skanowanie tylko indeksu, najlepiej byłoby mieć indeks wielokolumnowy na (exchange_symbol, symbol_id, time_open, high DESC)
do obsługi tego zapytania. Indeksuj kolumny w tej kolejności. Powiązane:
- Wielokolumnowy indeks i wydajność
W zależności od dystrybucji danych i innych szczegółów LEFT JOIN LATERAL
rozwiązaniem może być inna opcja. Powiązane:
- Jak znaleźć średnią wartości dla przedziałów czasowych w postgresie
- Zoptymalizuj zapytanie GROUP BY, aby pobrać najnowszy rekord na użytkownika
Poza tym EXPLAIN
plan przedstawia niektóre bardzo złe szacunki :
- https://explain.depesz.com/s/E5yI
Czy używasz bieżącego wersja Postgresa? Być może będziesz musiał popracować nad konfiguracją serwera - lub przynajmniej ustawić wyższe cele statystyk w odpowiednich kolumnach i bardziej agresywne ustawienia automatycznego odkurzania dla dużego stołu. Powiązane:
- Nie pozwól PostgreSQL-owi czasami wybierać złego planu zapytań
- Agresywne automatyczne odkurzanie w PostgreSQL