#postgresql #postgresql-9.6 #postgresql-13
Вопрос:
Мы обновляем базу данных с Postgres 9.6 до 13.4. Во время обновления мы наблюдали гораздо более низкую производительность запросов в новом экземпляре postgres 13.4.
Имеет некоторый смысл, что производительность в новом экземпляре будет ниже — однако мы видим, что запросы выполняются с существенно различными планами запросов (схемы БД и индексы, конечно, одинаковы).
Мы пытаемся понять причину различных планов запросов. Например, у нас есть запрос, который выполняется на порядки медленнее в новой версии 13.4 (например, 26 секунд против 200 мс).
Существует ли стандартный шаг в процессе миграции «обновление версии», которого нам не хватает, который помог бы объяснить более низкую производительность и значительно отличающиеся планы запросов?
Изменить: Пример запроса и различные планы запросов в Postgres 9.6 и 13.4
Запрос
EXPLAIN ANALYZE
SELECT
*
FROM
"my_table"
WHERE
"foo" = TRUE
AND "bar" = FALSE
AND("baz" > '2021-09-16 18:58:42.311 00'
OR("baz" = '2021-09-16 18:58:42.311 00'
AND "id" > 81353542))
ORDER BY
"baz" ASC,
"id" ASC
LIMIT 1;
План запросов Postgres 9.6:
Limit (cost=548886.22..548886.22 rows=1 width=152) (actual time=1232.777..1232.778 rows=1 loops=1)
-> Sort (cost=548886.22..549884.61 rows=1996789 width=152) (actual time=1232.776..1232.776 rows=1 loops=1)
Sort Key: baz, id
Sort Method: top-N heapsort Memory: 25kB
-> Bitmap Heap Scan on my_table (cost=30571.88..546889.43 rows=1996789 width=152) (actual time=531.993..1014.384 rows=1914762 loops=1)
Recheck Cond: ((foo AND (NOT bar) AND (baz > '2021-09-16 18:58:42.311 00'::timestamp with time zone)) OR (foo AND (NOT bar) AND (baz = '2021-09-16 18:58:42.311 00'::timestamp with time zone) AND (id > 81353542)))"
Filter: (foo AND (NOT bar))
Heap Blocks: exact=83762
-> BitmapOr (cost=30571.88..30571.88 rows=1996789 width=0) (actual time=512.609..512.609 rows=0 loops=1)
-> Bitmap Index Scan on my_table_foo_bar_ts_id (cost=0.00..30370.08 rows=1996789 width=0) (actual time=512.588..512.588 rows=2704908 loops=1)
Index Cond: ((foo = true) AND (bar = false) AND (baz > '2021-09-16 18:58:42.311 00'::timestamp with time zone))"
-> Bitmap Index Scan on my_table_foo_bar_ts_id (cost=0.00..2.12 rows=1 width=0) (actual time=0.020..0.020 rows=0 loops=1)
Index Cond: ((foo = true) AND (bar = false) AND (baz = '2021-09-16 18:58:42.311 00'::timestamp with time zone) AND (id > 21153592))"
Planning time: 0.181 ms
Execution time: 1233.303 ms
Postgres 13.4 План запросов:
Limit (cost=0.11..0.64 rows=1 width=152) (actual time=32871.675..32871.677 rows=1 loops=1)
-> Index Scan using my_table_foo_bar_ts_id on my_table (cost=0.11..1040476.82 rows=1962741 width=152) (actual time=32871.673..32871.674 rows=1 loops=1)
Index Cond: ((foo = true) AND (bar = false))
Filter: ((baz > '2021-09-16 18:58:42.311 00'::timestamp with time zone) OR ((baz = '2021-09-16 18:58:42.311 00'::timestamp with time zone) AND (id > 81353542)))"
Rows Removed by Filter: 18745951
Planning Time: 0.182 ms
Execution Time: 32871.705 ms
Комментарии:
1. Вы бежали
ANALYZE;
после обновления? (Еще лучше:VACUUM ANALYZE;
) См.: dba.stackexchange.com/a/187981/36842. Мы не знаем, что вы сделали, поэтому не знаем, пропустили ли вы что-то «стандартное». Если очистка и анализ базы данных не устраняют проблему, то покажите
EXPLAIN (ANALYZE, BUFFERS)
для запроса для каждой версии и покажите все настройки конфигурации, отличные от настроек по умолчанию.3. @ErwinBrandstetter мы запустили оба, результат не изменился. Я добавил образец запроса и планы запросов
4. @jjanes Я добавил пример запроса и различные планы запросов. Могу ли я предоставить какую-либо дополнительную информацию, которая могла бы помочь диагностировать происходящее?
5.
work_mem
Установлено одинаковое значение в обеих установках?
Ответ №1:
вот мои мысли.
postgresql не использует сканирование растрового индекса, потому что он сильно переоценил количество записей, которые, как он думал, вернутся, и решил выполнить «комбинированное сканирование индекса», а вместо этого просто один раз прочитать таблицу.
поэтому я предлагаю «проанализировать», чтобы убедиться, что ваша статистика актуальна, а также, возможно, ваши непристойности повреждены, поэтому попробуйте переиндексировать и повторите попытку
vaccume analyze;
analyze [table];
reindex;