В базе данных Postgresql 10.4
я вычисляю некоторую статистику по городам на основе данных, содержащихся в таблице, содержащей 2 129 498 записей и имеющей следующие индексы:
CREATE INDEX idx_activites_des_communes_code_commune_salaries ON activites_des_communes(code_commune, nombre_salaries DESC);
CREATE UNIQUE INDEX idx_activites_des_communes_code_commune_ape ON activites_des_communes(code_commune, ape);
CREATE INDEX idx_activites_des_communes_ape ON activites_des_communes(ape);
CREATE INDEX idx_activites_des_communes_nombre_entreprises ON activites_des_communes(nombre_entreprises);
CREATE INDEX idx_activites_des_communes_nombre_salaries ON activites_des_communes(nombre_salaries);
* * * * * * Для этой большой таблицы было сделано ANALYZE
.
В циклах для 36 000 городов я выполняю для каждого города следующие операторы в последовательности:
SELECT code_commune, nom, section_naf,
SUM(nombre_salaries) as nombre_salaries, sum(nombre_entreprises) as nombre_entreprises
FROM activites_des_communes
WHERE code_commune = :code_commune
GROUP BY code_commune, nom, section_naf
ORDER by code_commune, nom, sum(nombre_salaries) DESC;
Этот запрос имеет EXPLAIN
план:
"Sort (cost=2141.72..2143.14 rows=568 width=36)"
" Sort Key: nom, (sum(nombre_salaries)) DESC"
" -> HashAggregate (cost=2110.05..2115.73 rows=568 width=36)"
" Group Key: code_commune, nom, section_naf"
" -> Bitmap Heap Scan on activites_des_communes (cost=28.84..2102.94 rows=569 width=28)"
" Recheck Cond: ((code_commune)::text = '18205'::text)"
" -> Bitmap Index Scan on idx_activites_des_communes_code_commune_ape (cost=0.00..28.70 rows=569 width=0)"
" Index Cond: ((code_commune)::text = '18205'::text)"
Здесь я делаю некоторые вычисления в памяти и готов записать одну запись в таблицу, которая может быть пустой или нет.Я начинаю с удаления целевой записи, чтобы заменить ее после.
DELETE FROM activites_section_des_communes_par_salaries WHERE code_commune = :code_commune
Я проверил ее относительную SELECT
: она имеет для EXPLAIN
план:
"Index Scan using idx_activites_section_des_communes_par_salaries_code_commune on activites_section_des_communes_par_salaries (cost=0.29..8.30 rows=1 width=762)"
" Index Cond: ((code_commune)::text = '18205'::text)"
Затем я делаю INSERT
и иду в следующий город.
В начале моя программа работает быстро:
2018-12-21 18:18:17.001 INFO 6040 --- [nio-9090-exec-1] f.c.f.m.application.ActivitesController : Arboys en Bugey (01015) : Calcul des statistiques en cours.
2018-12-21 18:18:17.018 INFO 6040 --- [nio-9090-exec-1] f.c.f.m.application.ActivitesController : Arbigny (01016) : Calcul des statistiques en cours.
2018-12-21 18:18:17.026 INFO 6040 --- [nio-9090-exec-1] f.c.f.m.application.ActivitesController : Argis (01017) : Calcul des statistiques en cours.
2018-12-21 18:18:17.051 INFO 6040 --- [nio-9090-exec-1] f.c.f.m.application.ActivitesController : Armix (01019) : Calcul des statistiques en cours.
2018-12-21 18:18:17.068 INFO 6040 --- [nio-9090-exec-1] f.c.f.m.application.ActivitesController : Ars-sur-Formans (01021) : Calcul des statistiques en cours.
Но, выполняя свою работу, она замедляется и замедляетсяпо прошествии времени:
2018-12-21 18:53:11.088 INFO 5632 --- [nio-9090-exec-1] f.c.f.m.application.ActivitesController : Lapouyade (33230) : Calcul des statistiques en cours.
2018-12-21 18:53:11.379 INFO 5632 --- [nio-9090-exec-1] f.c.f.m.application.ActivitesController : Laroque (33231) : Calcul des statistiques en cours.
2018-12-21 18:53:11.671 INFO 5632 --- [nio-9090-exec-1] f.c.f.m.application.ActivitesController : Lartigue (33232) : Calcul des statistiques en cours.
2018-12-21 18:53:12.254 INFO 5632 --- [nio-9090-exec-1] f.c.f.m.application.ActivitesController : Latresne (33234) : Calcul des statistiques en cours..
2018-12-21 18:53:12.546 INFO 5632 --- [nio-9090-exec-1] f.c.f.m.application.ActivitesController : Lavazan (33235) : Calcul des statistiques en cours.
Вот мои вопросы:
1) Мой выбор индексов кажется неумным для обработки запроса, который я хочу выполнить: тот, который имеет GROUP BY
и ORDER BY
.
2) Как можно объяснить замедление?
С уважением,