sql >> Databáze >  >> RDS >> PostgreSQL

Pomalé LEFT JOIN na CTE s časovými intervaly

Správnost především :Mám podezření na chybu ve vašem dotazu:

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

Na rozdíl od mé odkazované odpovědi se připojujete v časovém intervalu :(time_open, time_close] . Způsob, jakým to uděláte, vylučuje řádky v tabulce, kde interval překračuje hranice segmentu. Počítají se pouze intervaly plně obsažené v jednom segmentu. Nemyslím si, že je to zamýšleno?

Jednoduchou opravou by bylo rozhodnout o členství v segmentu na základě time_open (nebo time_close ) sám. Pokud chcete nadále pracovat s oběma, musíte definovat přesně jak se vypořádat s intervaly překrývajícími se s více segmenty.

Také hledáte max(high) na kbelík, což se svou povahou liší od count(*) v mé odkazované odpovědi.

A vaše kbelíky jsou jednoduché intervaly za hodinu?

Pak můžeme radikálně zjednodušit. Práce pouze s 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;

Související:

  • Převzorkování dat časové řady

Je těžké mluvit o další optimalizaci výkonu, zatímco základy jsou nejasné. A potřebovali bychom více informací.

Jsou WHERE proměnná podmínek?
Kolik různých hodnot v exchange_symbol a symbol_id ?
Prům. velikost řádku? Za co získáte:

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

Je tabulka pouze pro čtení?

Za předpokladu, že vždy filtrujete podle exchange_symbol a symbol_id a hodnoty jsou proměnlivé, vaše tabulka je pouze pro čtení nebo autovakuum může držet krok se zatížením zápisu, takže můžeme doufat v skenování pouze s indexem, nejlépe byste měli vícesloupcový index na (exchange_symbol, symbol_id, time_open, high DESC) na podporu tohoto dotazu. Indexujte sloupce v tomto pořadí. Související:

  • Vícesloupcový index a výkon

V závislosti na distribuci dat a dalších podrobnostech LEFT JOIN LATERAL řešením může být jiná možnost. Související:

  • Jak najít průměr hodnot pro časové intervaly v postgres
  • Optimalizujte dotaz GROUP BY pro získání nejnovějšího záznamu na uživatele

Kromě toho všeho EXPLAIN plán vykazuje některévelmi špatné odhady :

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

Používáte aktuální verze Postgresu? Možná budete muset zapracovat na konfiguraci serveru – nebo alespoň nastavit vyšší statistické cíle pro relevantní sloupce a agresivnější nastavení autovakuování pro velký stůl. Související:

  • Zabraňte PostgreSQL, aby někdy zvolil špatný plán dotazů
  • Agresivní automatické vakuování na PostgreSQL



  1. Názvy procesů PostgreSQL na Solaris

  2. PostgreSQL:Vytvořte index pro booleovský sloupec

  3. Jak interpretovat hodnotu txid_current() PosgreSQL

  4. Replikace MySQL a selhání založené na GTID – hluboký ponor do chybných transakcí