Это связано с двумя другими вопросами, которые я написал (похоже, я должен опубликовать это как новый вопрос) - обратная связь помогла, но я думаю, что та же проблема вернется в следующий раз, когда мне нужно будет вставить данные. Все шло медленно, что заставило меня временно удалить некоторые старые данные, так что в таблице, к которой я обращаюсь, осталось только 2 месяца.
Стратегия индексирования для различных комбинаций предложений WHERE, вкл. текстовые шаблоны
Как получить запрос date_part для индекса попадания?
Подробное описание на этот раз - надеюсь, это поможет точно определить проблему:
- PG версия 10.7 (работает на герою
- Общий размер БД: 18,4 ГБ (содержит данные за 2 месяца и будет расти примерно с одинаковой скоростью каждый месяц)
- 15 ГБ ОЗУ
- Общее доступное хранилище: 512 ГБ
- Самая большая таблица (та, над которой работает самый медленный запрос) - 9,6 ГБ (это самый большой кусок всей БД) - около 10 миллионов записей
Схема самой большой таблицы:
-- Table Definition ----------------------------------------------
CREATE TABLE reportimpression (
datelocal timestamp without time zone,
devicename text,
network text,
sitecode text,
advertisername text,
mediafilename text,
gender text,
agegroup text,
views integer,
impressions integer,
dwelltime numeric
);
-- Indices -------------------------------------------------------
CREATE INDEX reportimpression_feb2019_index ON reportimpression(datelocal timestamp_ops) WHERE datelocal >= '2019-02-01 00:00:00'::timestamp without time zone AND datelocal < '2019-03-01 00:00:00'::timestamp without time zone;
CREATE INDEX reportimpression_mar2019_index ON reportimpression(datelocal timestamp_ops) WHERE datelocal >= '2019-03-01 00:00:00'::timestamp without time zone AND datelocal < '2019-04-01 00:00:00'::timestamp without time zone;
CREATE INDEX reportimpression_jan2019_index ON reportimpression(datelocal timestamp_ops) WHERE datelocal >= '2019-01-01 00:00:00'::timestamp without time zone AND datelocal < '2019-02-01 00:00:00'::timestamp without time zone;
Медленный запрос:
SELECT
date_part('hour', datelocal) AS hour,
SUM(CASE WHEN gender = 'male' THEN views ELSE 0 END) AS male,
SUM(CASE WHEN gender = 'female' THEN views ELSE 0 END) AS female
FROM reportimpression
WHERE
datelocal >= '3-1-2019' AND
datelocal < '4-1-2019'
GROUP BY date_part('hour', datelocal)
ORDER BY date_part('hour', datelocal)
Диапазон дат в этом запросе обычно равен целому месяцу (он принимает пользовательский ввод из веб-отчета) - как вы можете видеть, я попытался создать индекс для данных за каждый месяц. Это помогло, но, насколько я могу судить, если запрос не был запущен недавно (помещение результатов в кэш), он все равно может занять до минуты.
Объяснить результаты анализа:
Finalize GroupAggregate (cost=1035890.38..1035897.86 rows=1361 width=24) (actual time=3536.089..3536.108 rows=24 loops=1)
Group Key: (date_part('hour'::text, datelocal))
-> Sort (cost=1035890.38..1035891.06 rows=1361 width=24) (actual time=3536.083..3536.087 rows=48 loops=1)
Sort Key: (date_part('hour'::text, datelocal))
Sort Method: quicksort Memory: 28kB
-> Gather (cost=1035735.34..1035876.21 rows=1361 width=24) (actual time=3535.926..3579.818 rows=48 loops=1)
Workers Planned: 1
Workers Launched: 1
-> Partial HashAggregate (cost=1034735.34..1034740.11 rows=1361 width=24) (actual time=3532.917..3532.933 rows=24 loops=2)
Group Key: date_part('hour'::text, datelocal)
-> Parallel Index Scan using reportimpression_mar2019_index on reportimpression (cost=0.09..1026482.42 rows=3301168 width=17) (actual time=0.045..2132.174 rows=2801158 loops=2)
Planning time: 0.517 ms
Execution time: 3579.965 ms
Я бы не подумал, что 10 миллионов записей будет слишком много, особенно если учесть, что я недавно увеличил план PG, на который я нацелился, чтобы попытаться использовать ресурсы, поэтому я предполагаю, что проблема все еще не решена. либо мои индексы, либо мои запросы не очень эффективны.