sql >> Databasteknik >  >> RDS >> PostgreSQL

Långsam LEFT JOIN på CTE med tidsintervall

Riktigt först :Jag misstänker ett fel i din fråga:

 LEFT JOIN historical_ohlcv ohlcv ON ohlcv.time_open >= g.start_time
                                 AND ohlcv.time_close < g.end_time

Till skillnad från mitt refererade svar går du med på ett tidsintervall :(time_open, time_close] . Sättet du gör det utesluter rader i tabellen där intervallet korsar hinkgränserna. Endast intervaller som ingår i en enda hink räknas. Jag tror inte att det är meningen?

En enkel lösning skulle vara att bestämma bucket-medlemskap baserat på time_open (eller time_close ) ensam. Om du vill fortsätta arbeta med båda måste du definiera exakt hur man hanterar intervaller som överlappar med flera hinkar.

Du letar också efter max(high) per hink, vilket till sin natur skiljer sig från count(*) i mitt refererade svar.

Och dina hinkar är enkla intervaller per timme?

Då kan vi förenkla radikalt. Arbetar med bara 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;

Relaterat:

  • Sampla om tidsseriedata

Det är svårt att prata om ytterligare prestandaoptimering medan grunderna är oklara. Och vi skulle behöva mer information.

Är WHERE villkorsvariabel?
Hur många distinkta värden i exchange_symbol och symbol_id ?
Gen. radstorlek? Vad får du för:

SELECT avg(pg_column_size(t)) FROM historical_ohlcv t TABLESAMPLE SYSTEM (0.1);

Är tabellen skrivskyddad?

Förutsatt att du alltid filtrerar på exchange_symbol och symbol_id och värdena är variabla, din tabell är skrivskyddad eller så kan autovakuum hålla jämna steg med skrivbelastningen så att vi kan hoppas på enbart indexskanningar, det är bäst att ha ett flerkolumnindex(exchange_symbol, symbol_id, time_open, high DESC) för att stödja denna fråga. Indexera kolumner i denna ordning. Relaterat:

  • Flerkolumnindex och prestanda

Beroende på datadistribution och andra detaljer en LEFT JOIN LATERAL lösning kan vara ett annat alternativ. Relaterat:

  • Hur man hittar ett genomsnitt av värden för tidsintervall i postgres
  • Optimera GROUP BY-frågan för att hämta senaste posten per användare

Bortsett från allt det, du EXPLAIN planen visar några mycket dåliga uppskattningar :

  • https://explain.depesz.com/s/E5yI

Använder du en ström version av Postgres? Du kanske måste arbeta med din serverkonfiguration - eller åtminstone sätta högre statistikmål på relevanta kolumner och mer aggressiva autovakuuminställningar för det stora bordet. Relaterat:

  • Få PostgreSQL från att ibland välja en dålig frågeplan
  • Aggressiv autovacuum på PostgreSQL



  1. Hur man automatiserar PostgreSQL 12-replikering och failover med repmgr – Del 2

  2. Fatalt fel:Oupptäckt fel:Anrop till odefinierad funktion mysql_connect()

  3. Hur man skapar en MySQL-databas i cPanel

  4. Hur man inkluderar exkluderade rader i ÅTERKOMMANDE från INFOGA ... VID KONFLIKT