Каждый день рано утром задание pgAgent обновляет содержимое таблицы A из таблицы B моей базы данных PostgreSQL 8.4. Таблица A содержит около 140 тыс. Записей в 91 столбце и имеет два индекса - один как часть PRIMARY KEY, а другой - индекс GIST в столбце геометрии POINT PostGIS.
Чтобы ускорить процесс, задание сбрасывает индекс в столбце геометрии, перед удалением записей в таблице A и вставкой записей из таблицы B индекс воссоздается. Все это делается, когда демон автовакуума начинает работать, когда ему это нравится (примерно через десять минут после сравнения статистики работы и статистики таблицы по времени завершения работы и времени работы автоочистки).
После проверки таблицы сегодня утром после всего того, что произошло, статистика таблицы сообщила мне, что размер таблицы составляет 272 МБ, размер таблицы TOAST - 8192 байта, а размер индекса - 23 МБ. Это казалось довольно большим, поэтому я ввел команду REINDEX для таблицы, и размер индекса сократился до 9832 КБ.
Мой вопрос (ы) заключается в следующем:
Почему REINDEX, очевидно, так сильно уменьшает размер индексов, когда индексы (или, по крайней мере, индекс столбца геометрии) были построены заново с нуля? Должен ли я убедиться, что таблица была очищена пылесосом / проанализирована до построения индексов? Не является ли снижение индекса по первичному ключу фактором в этом? Что мне не хватает?
источник
ANALYZE
сообщаемый размер тоже уменьшится.Ответы:
Если оператор CREATE INDEX видит, что другой сеанс содержит активный снимок, который все еще может быть заинтересован в удаленных записях, то он включает эти удаленные записи в новый индекс.
Точно так же, если REINDEX видит, что другой сеанс содержит активный снимок, который может по-прежнему интересоваться удаленными записями, он включает эти удаленные записи в новый индекс.
Если VACUUM видит, что другой сеанс содержит активный снимок, который все еще может быть заинтересован в удаленных записях, он сохраняет эти записи в таблице. И затем REINDEX или CREATE INDEX также необходимо перенести их в новый индекс, пока существует моментальный снимок.
Как только появятся или не появятся моментальные снимки, которые могли бы видеть удаленные строки, VACUUM может удалить их из таблицы. Но CREATE INDEX или REINDEX также могут просто не перенести их в новый индекс, независимо от того, удалось ли VACUUM удалить их из списка или нет.
Таким образом, в вашем сценарии роль VACUUM между начальным CREATE INDEX и REINDEX, вероятно, состоит в том, чтобы просто занимать время, в течение которого, как мы надеемся, ваша долгосрочная транзакция исчезнет сама по себе и удалит мешающий снимок.
источник
Испытав разные порядки выполнения, кажется, что выполнение VACUUM перед инструкцией REINDEX - единственный способ добиться уменьшения размера, возможно, потому, что невостребованное пространство добавляет к индексу (индексация удаленных записей?). Принудительное переписывание таблицы с помощью
делает то же самое, поскольку очищает неиспользуемое пространство.
Наличие VACUUM в середине процесса немного нарушает поток, поскольку необходимо выполнить команду VACUUM вне транзакции.
источник