Я недавно начал использовать postgresql 11 и столкнулся с одним интересным поведением.
Я создал таблицу "преобразований" с разделами (logdate - это ключ).
CREATE TABLE conversions(
.....
logdate timestamp without time zone,
....
) PARTITION BY RANGE (logdate);
CREATE INDEX ON conversions(logdate);
--
CREATE unique INDEX conversions_log_id_idx ON conversions(logdate, id);
CREATE INDEX conversions_log_is_created_idx ON conversions(logdate, is_created);
Сокращение раздела работает для операторов SELECT (как описано в документации):
SELECT *
FROM conversions
WHERE logdate BETWEEN to_date('2017-09-01 00:00:00','YYYY-MM-DD HH24:MI:SS') AND to_date('2017-09-08 23:59:59','YYYY-MM-DD HH24:MI:SS');
"Append (cost=0.42..11134.74 rows=13051 width=1715)"
" Subplans Removed: 12"
" -> Index Scan using conversions_y2017q03_logdate_idx on conversions_y2017q03 (cost=0.42..10962.37 rows=13038 width=1715)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_default_logdate_is_created_idx on conversions_default (cost=0.14..8.16 rows=1 width=2030)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
Это работает хорошо, вы можете видеть это раньше.
Но это не работает для операторов обновления.
Например:
UPDATE conversions
SET is_created = 'N'
WHERE logdate BETWEEN to_date('2017-09-01 00:00:00','YYYY-MM-DD HH24:MI:SS') AND to_date('2017-09-08 23:59:59','YYYY-MM-DD HH24:MI:SS')
"Update on conversions (cost=0.42..11069.48 rows=13051 width=1727)"
" Update on conversions_y2016q04"
" Update on conversions_y2017q01"
" Update on conversions_y2017q02"
" Update on conversions_y2017q03"
" Update on conversions_y2017q04"
" Update on conversions_y2018q01"
" Update on conversions_y2018q02"
" Update on conversions_y2018q03"
" Update on conversions_y2018q04"
" Update on conversions_y2019q01"
" Update on conversions_y2019q02"
" Update on conversions_y2019q03"
" Update on conversions_y2019q04"
" Update on conversions_default"
" -> Index Scan using conversions_y2016q04_logdate_is_created_idx on conversions_y2016q04 (cost=0.42..8.44 rows=1 width=1661)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2017q01_logdate_is_created_idx on conversions_y2017q01 (cost=0.42..8.45 rows=1 width=1804)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2017q02_logdate_is_created_idx on conversions_y2017q02 (cost=0.42..8.45 rows=1 width=1805)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2017q03_logdate_idx on conversions_y2017q03 (cost=0.42..10962.37 rows=13038 width=1727)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2017q04_logdate_id_idx on conversions_y2017q04 (cost=0.29..8.31 rows=1 width=1699)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2018q01_logdate_is_created_idx on conversions_y2018q01 (cost=0.14..8.16 rows=1 width=2036)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2018q02_logdate_is_created_idx on conversions_y2018q02 (cost=0.14..8.16 rows=1 width=2036)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2018q03_logdate_is_created_idx on conversions_y2018q03 (cost=0.14..8.16 rows=1 width=2036)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2018q04_logdate_is_created_idx on conversions_y2018q04 (cost=0.14..8.16 rows=1 width=2036)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2019q01_logdate_is_created_idx on conversions_y2019q01 (cost=0.14..8.16 rows=1 width=2036)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2019q02_logdate_is_created_idx on conversions_y2019q02 (cost=0.14..8.16 rows=1 width=2036)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2019q03_logdate_is_created_idx on conversions_y2019q03 (cost=0.14..8.16 rows=1 width=2036)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_y2019q04_logdate_is_created_idx on conversions_y2019q04 (cost=0.14..8.16 rows=1 width=2036)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
" -> Index Scan using conversions_default_logdate_is_created_idx on conversions_default (cost=0.14..8.16 rows=1 width=2036)"
" Index Cond: ((logdate >= to_date('2017-09-01 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (logdate <= to_date('2017-09-08 23:59:59'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))"
Похоже, что Postgresql использует индекс для поиска необходимых разделов.
Это хорошее поведение?Вы мысли?