Из них нужно обновить одно поле в jsonb поле у шести миллионов. Запускаю update set.. where... и запрос очень долго выполняется. Больше шести часов. Я думаю он завис. Что может мешать? Индексы?(есть индекс на jsonb поле, есть индекс ещё на одно поле)
Быстрее всего обновлять пачками по 1000 - 100000 записей. В зависимости от погоды и число проще всего подобрать эмпирическим путём.
> Я думаю он завис. Почему Вы так думаете? Что в pg_stat_activity? Может быть, что-то "нехорошее" есть в логах? > Индексы?(есть индекс на jsonb поле, есть индекс ещё на одно поле) А какие индексы вообще есть на таблице (покажите \d+ your_table, например)? А, и какая это полная версия PostgreSQL?
не смогу глянуть pg_stat_activity. У меня rds и я так и не поставил ту утиллиту, которую в прошлый раз советовали. На этой таблице четыре индекса: PK, FK(в моих 6 миллионах записях он не используется), индекс по строковому полю для ускорения поиска, индекс по уникальности для комбинации строковое поле + поле в jsonb поле
> не смогу глянуть pg_stat_activity. Почему?! > У меня rds и я так и не поставил ту утиллиту, которую в прошлый раз советовали. Если он настолько отличается от vanilla PostgreSQL, то все вопросы уже не сюда. ;) Но, по-моему, Вы что-то путаете. > На этой таблице четыре индекса Легче же показать \d, а не пересказывать.
блин, перепутал)))) да, глянул pg_stat_activity - там есть два процесса с моим апдейтом. У одного event DataFileRead c типом IO, у второго transactionid c типом Lock
Хмм... а почему два-то? Один же должен быть? > У одного event DataFileRead c типом IO Т.е. работает, что-то читает (или пытается — точно нет в логах проблем?).
тот вчерашний, который c типом IO. У него статус поменялся вчера в 9. Отменил этот запрос я сегодня утром. Думаю он тоже завис. Я как-нибудь эти два процесса кильнуть могу?
а можете подробнее объяснить. если взять вводную про 69млн. нашли магическое число пусть 10к записей, а дальше? на 1 раз понятно, например cte по условию первые 10к записей и update записей
Сначала я пробовал with... update. Минут через сорок (условно) оно плавно начинало тормозить и раком вставало. Но эффективнее всего в старых версиях было в транзакции делать через явную темповую таблицу с id-шками. create temp table ... select for update ... limit 10000; Обновляем, дропаем табличку и всё заново.
не совсем понял чем это лучше with temp_table as( select id.... ... limit 10000) update .... почему с cte все тормозило, а с постоянным пересозданием временной таблицы все работало приемлимо?
блоат, статистика. Короче, от красивостей cte ( такого слова я тогда не знал ) пришлось отказаться. Эффективнее всего фигачить по заранее сделанному списку с обращениями по PK
ясно. если бы вы не объяснили, я бы считал, что с cte лучше. спасибо.
Я много чудес насмотрелся. Самый прикол с перекладыванием данных из партицию в партицию был ( перераспределить для уменьшения числа партиций или наоброт, нарезать слишком выросшую таблицу ). Как только последнюю пачку данных удаляеешь из таблицы ( а она большая была и стала один сплошной блоат ), планировщику крышу рвёт и он начинает по ней сексканить. Вот тут надо успеть или отвакуумить или analyse сделать.
да, часто бывает. проще запретить merge_join-ы для всего кластера, тогда плаировщик не будет пытаться искать граничные значения, когда там дохрена мертвых строк и надо перебирать всё до первой живой
Буду знать, спасибо.
Обсуждают сегодня