Korrekthed først :Jeg har mistanke om en fejl i din forespørgsel:
LEFT JOIN historical_ohlcv ohlcv ON ohlcv.time_open >= g.start_time
AND ohlcv.time_close < g.end_time
I modsætning til mit refererede svar tilmelder du dig på et tidsinterval :(time_open, time_close]
. Den måde, du gør det på, udelukker rækker i tabellen, hvor intervallet krydser spandegrænser. Kun intervaller fuldt indeholdt i en enkelt spand tæller. Jeg tror ikke, det er meningen?
En simpel løsning ville være at beslutte bucket-medlemskab baseret på time_open
(eller time_close
) alene. Hvis du vil fortsætte med at arbejde med begge, skal du definere præcist hvordan man håndterer intervaller, der overlapper med flere spande.
Du leder også efter max(high)
pr. spand, hvilket er forskelligt fra count(*)
i mit refererede svar.
Og dine spande er simple intervaller i timen?
Så kan vi forenkle radikalt. Arbejder kun med 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;
Relateret:
- Genprøve på tidsseriedata
Det er svært at tale om yderligere ydeevneoptimering, mens det grundlæggende er uklart. Og vi har brug for flere oplysninger.
Er WHERE
betingelser variabel?
Hvor mange forskellige værdier i exchange_symbol
og symbol_id
?
Gns. række størrelse? Hvad får du for:
SELECT avg(pg_column_size(t)) FROM historical_ohlcv t TABLESAMPLE SYSTEM (0.1);
Er tabellen skrivebeskyttet?
Forudsat at du altid filtrerer på exchange_symbol
og symbol_id
og værdier er variable, din tabel er skrivebeskyttet eller autovakuum kan holde trit med skrivebelastningen, så vi kan håbe på kun indeksscanninger, du ville bedst have et flerkolonneindeks på (exchange_symbol, symbol_id, time_open, high DESC)
for at understøtte denne forespørgsel. Indekskolonner i denne rækkefølge. Relateret:
- Flerkolonneindeks og ydeevne
Afhængigt af datadistribution og andre detaljer en LEFT JOIN LATERAL
løsning kan være en anden mulighed. Relateret:
- Sådan finder du et gennemsnit af værdier for tidsintervaller i postgres
- Optimer GROUP BY-forespørgsel for at hente seneste post pr. bruger
Bortset fra alt det, du EXPLAIN
planen udstiller nogle meget dårlige skøn :
- https://explain.depesz.com/s/E5yI
Bruger du en aktuel version af Postgres? Du skal muligvis arbejde på din serverkonfiguration - eller i det mindste sætte højere statistikmål på relevante kolonner og mere aggressive autovakuumindstillinger for det store bord. Relateret:
- Hold PostgreSQL fra nogle gange at vælge en dårlig forespørgselsplan
- Aggressiv autovakuum på PostgreSQL