PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Powolne LEFT JOIN na CTE z interwałami czasowymi

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oblicz procenty z SUM() w tym samym zapytaniu SELECT sql

  2. Rozpakuj wiele tablic równolegle

  3. Wyłącz sprawdzanie kluczy obcych PostgreSQL dla migracji

  4. Ustawianie limitu czasu połączenia z PDO

  5. Postgres:BŁĄD:plan w pamięci podręcznej nie może zmieniać typu wyniku