Долгое ожидание запроса SELECT для таблицы с 70 миллионами записей. Как повысить производительность?

#postgresql

#postgresql

Вопрос:

У меня есть таблица в Postgres с более чем 70 миллионами записей, которая связывает температуру с определенным временем (днем) и пространством (метеорологическая станция). Мне нужно выполнить некоторые вычисления с учетом периода времени и набора метеорологических станций, таких как сумма, среднее значение, квартиль и нормальное значение. Я использую его, для возврата требуется 30 секунд. Как я могу улучшить это ожидание?

Это explain(analyze, buffers) select avg(p) as rain FROM waterbalances group by extract(month from date), extract(year from date); :

                                                                            QUERY PLAN                                   
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
 Finalize GroupAggregate  (cost=3310337.68..3314085.15 rows=13836 width=24) (actual time=21252.008..21252.624 rows=478 loops=1)
   Group Key: (date_part('month'::text, (date)::timestamp without time zone)), (date_part('year'::text, (date)::timestamp without time zone))
   Buffers: shared hit=6335 read=734014
   ->  Gather Merge  (cost=3310337.68..3313566.30 rows=27672 width=48) (actual time=21251.984..21261.693 rows=1432 loops=1)
         Workers Planned: 2
         Workers Launched: 2
         Buffers: shared hit=15841 read=2195624
         ->  Sort  (cost=3309337.66..3309372.25 rows=13836 width=48) (actual time=21130.846..21130.862 rows=477 loops=3)               Sort Key: (date_part('month'::text, (date)::timestamp without time zone)), (date_part('year'::text, (date)::timestamp without time zone))
               Sort Method: quicksort  Memory: 92kB
               Worker 0:  Sort Method: quicksort  Memory: 92kB
               Worker 1:  Sort Method: quicksort  Memory: 92kB
               Buffers: shared hit=15841 read=2195624
               ->  Partial HashAggregate  (cost=3308109.29..3308386.01 rows=13836 width=48) (actual time=21130.448..21130.618 rows=477 loops=3)
                     Group Key: date_part('month'::text, (date)::timestamp without time zone), date_part('year'::text, (date)::timestamp without time zone)
                     Buffers: shared hit=15827 read=2195624
                     ->  Parallel Seq Scan on waterbalances  (cost=0.00..3009020.66 rows=39878483 width=24) (actual time=1.528..15460.388 rows=31914000 loops=3)
                           Buffers: shared hit=15827 read=2195624
 Planning Time: 7.621 ms
 Execution Time: 21262.552 ms
(20 rows)
 

Комментарии:

1. Ни одна из ваших данных не находилась в общих буферах, и части таблицы никогда не выбирались ранее (следовательно, данные были загрязнены и записаны). Я не вижу, чтобы вычислялась сумма или среднее значение. 38 секунд для 17 ГБ данных — это не так уж плохо, не так ли? Вероятно, вам нужны предварительно агрегированные материализованные представления.

2. width=137 кажется довольно большим. Каково определение вашей таблицы (таблиц)? Нормализована ли ваша модель данных?