На първо място коректността :Подозирам, че има грешка във вашата заявка:
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