sql >> Database >  >> RDS >> PostgreSQL

Langzaam LEFT JOIN op CTE met tijdsintervallen

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



  1. Hoe numerieke typen uit MySQL te halen met PDO?

  2. Maak een Excel-bestand (.xlsx) met PL/SQL

  3. Selecteer statement om duplicaten op bepaalde velden te vinden

  4. SELECT DISTINCT is langzamer dan verwacht op mijn tafel in PostgreSQL