Correctie eerst :Ik vermoed een fout in uw zoekopdracht:
LEFT JOIN historical_ohlcv ohlcv ON ohlcv.time_open >= g.start_time
AND ohlcv.time_close < g.end_time
In tegenstelling tot mijn antwoord waarnaar wordt verwezen, doe je mee op een tijd interval :(time_open, time_close]
. De manier waarop u dit doet, sluit rijen in de tabel uit waar het interval de bucketgrenzen overschrijdt. Alleen intervallen die volledig zijn opgenomen in een enkele bucket tellen. Ik denk niet dat dat de bedoeling is?
Een eenvoudige oplossing zou zijn om het lidmaatschap van een bucket te bepalen op basis van time_open
(of time_close
) alleen. Als je met beide wilt blijven werken, moet je exact . definiëren hoe om te gaan met intervallen die overlappen met meerdere buckets.
U zoekt ook naar max(high)
per bucket, wat van aard verschilt van count(*)
in mijn antwoord waarnaar wordt verwezen.
En uw emmers zijn eenvoudige intervallen per uur?
Dan kunnen we radicaal vereenvoudigen. Werken met slechts 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;
Gerelateerd:
- Resample op tijdreeksgegevens
Het is moeilijk om over verdere prestatie-optimalisatie te praten, terwijl de basis onduidelijk is. En we hebben meer informatie nodig.
Zijn WHERE
voorwaarden variabele?
Hoeveel verschillende waarden in exchange_symbol
en symbol_id
?
Gem. rij grootte? Waar krijg je voor:
SELECT avg(pg_column_size(t)) FROM historical_ohlcv t TABLESAMPLE SYSTEM (0.1);
Is de tabel alleen-lezen?
Ervan uitgaande dat u altijd filtert op exchange_symbol
en symbol_id
en waarden zijn variabel, uw tabel is alleen-lezen of autovacuum kan de schrijfbelasting bijhouden, dus we kunnen hopen op scans met alleen index, u kunt het beste een index met meerdere kolommen hebben op (exchange_symbol, symbol_id, time_open, high DESC)
om deze vraag te ondersteunen. Indexeer kolommen in deze volgorde. Gerelateerd:
- Index en prestaties met meerdere kolommen
Afhankelijk van de gegevensdistributie en andere details een LEFT JOIN LATERAL
oplossing is misschien een andere optie. Gerelateerd:
- Een gemiddelde van waarden voor tijdsintervallen in postgres vinden
- Optimaliseer de GROUP BY-query om het laatste record per gebruiker op te halen
Afgezien van dat alles, EXPLAIN
plan vertoont enkele zeer slechte schattingen :
- https://explain.depesz.com/s/E5yI
Gebruikt u een huidige versie van Postgres? Mogelijk moet u aan uw serverconfiguratie werken - of op zijn minst hogere statistische doelen instellen op relevante kolommen en agressievere autovacuüminstellingen voor de grote tafel. Gerelateerd:
- Voorkom dat PostgreSQL soms een slecht queryplan kiest
- Agressief autovacuüm op PostgreSQL