PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Бавно LEFT JOIN на CTE с интервали от време

На първо място коректността :Подозирам, че има грешка във вашата заявка:

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

За разлика от посочения ми отговор, вие се присъединявате на интервал :(time_open, time_close] . Начинът, по който го правите, изключва редове в таблицата, където интервалът пресича границите на кофата. Отчитат се само интервалите, изцяло съдържащи се в една кофа. Не мисля, че това е предвидено?

Една проста корекция би била да решите членство в групата въз основа на time_open (или time_close ) сам. Ако искате да продължите да работите и с двете, трябва да дефинирате точно как да се справите с интервали, припокриващи се с множество кофи.

Освен това търсите max(high) на кофа, което е различно по естество от count(*) в посочения ми отговор.

И вашите кофи са прости интервали на час?

Тогава можем радикално да опростим. Работете само с 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;

Свързано:

  • Повторна извадка на данни от времеви серии

Трудно е да се говори за по-нататъшно оптимизиране на производителността, докато основите са неясни. И ще ни трябва повече информация.

Са WHERE условия променлива?
Колко различни стойности в exchange_symbol и symbol_id ?
Ср. размер на реда? За какво получавате:

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

Таблицата само за четене ли е?

Ако приемем, че винаги филтрирате по exchange_symbol и symbol_id и стойностите са променливи, вашата таблица е само за четене или автовакуумът може да се справи с натоварването при запис, така че можем да се надяваме на сканиране само с индекс, най-добре ще имате индекс с няколко колони на (exchange_symbol, symbol_id, time_open, high DESC) за да подкрепи тази заявка. Индексни колони в този ред. Свързано:

  • Многоколонов индекс и ефективност

В зависимост от разпределението на данните и други подробности LEFT JOIN LATERAL решението може да е друга опция. Свързано:

  • Как да намеря средни стойности за интервали от време в postgres
  • Оптимизирайте заявката GROUP BY, за да извлечете последния запис на потребител

Освен всичко това, вие EXPLAIN план експонати някоимного лоши оценки :

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

Използвате ли ток версия на Postgres? Може да се наложи да поработите върху конфигурацията на сървъра си - или поне да зададете по-високи статистически цели за съответните колони и по-агресивни настройки за автоматично вакуумиране за голямата маса. Свързано:

  • Пазете PostgreSQL понякога да избира лош план за заявка
  • Агресивно автоматично вакуумиране на PostgreSQL



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да скриете декорацията на набора от резултати в изхода на Psql

  2. Хибернация, Postgresql:Колона x е от тип oid, но изразът е от тип байт

  3. Подаване на param към DB .execute за списък WHERE IN... INT

  4. GroupingError:ERROR:колоната трябва да се появи в клаузата GROUP BY или да се използва в агрегатна функция

  5. Как да инсталирам само клиентските инструменти за PostgreSQL на Windows?