Запрос не обновляет строки, но возвращает успешно

Я пытаюсь обновить таблицу из другой, запрос завершается успешно, но строки не обновляются. Каждая таблица содержит ~32 млн строк. Я использую PostgreSQL 11.12.

Вот 2 таблицы (я удалил столбцы, не используемые в запросе):

CREATE TABLE IF NOT EXISTS public.sirene_geo
(
    siret character varying(50) NOT NULL,
    x numeric,
    y numeric,
    CONSTRAINT sirene_geo_etablissement_pkey PRIMARY KEY (siret)
)

CREATE TABLE IF NOT EXISTS public.sirene_eta
(
    siret character varying(50) NOT NULL,  
    latitude numeric,
    longitude numeric,
    CONSTRAINT sirene_stock_etablissement_pk PRIMARY KEY (siret)
)

Запрос на обновление:

UPDATE sirene_eta eta
SET longitude = x,
    latitude = y
FROM sirene_geo geo
WHERE eta.siret = geo.siret

В pgAdmin (v5.4) для поля «Затронутые строки» указано -1.
Postgres использует стратегию хэш-соединения для завершения обновления. Кроме того, в sirene_geo меньше строк, чем в sirene_eta, но Postgres строит хеш-таблицу на sirene_geo (что приводит к несовпадению некоторых строк).

Когда я пытаюсь выполнить обновление с ограничением внутри таблицы подзапросов, оно работает, но использует стратегию вложенного цикла, которая определенно не подходит для обновления всей таблицы.

Обновление:
Нет параллельной записи. Я проверил журнал, и действительно, есть ошибка:

ERROR: could not write to file "base/pgsql_tmp/pgsql_tmp9264.8256": No space left on device

Нет такого понятия, как «Постгре». wiki.postgresql.org/wiki/Identity_Guidelines Укажите свою версию Postgres и pgAdmin. Мой pgAdmin4 (текущая версия 6.7) сообщает стандартный тег команды «UPATE 0», когда ни одна строка не была затронута. Я подозреваю, что вы столкнулись с ошибкой. Время соединения вышло? Или из памяти? Вы должны увидеть правильное сообщение об ошибке! Проверьте логи вашей БД.

Erwin Brandstetter 20.03.2022 03:49

Кроме того, если есть одновременная запись, вы можете легко столкнуться с взаимоблокировками при одновременном обновлении 32M строк в случайном порядке ... Есть ли?

Erwin Brandstetter 20.03.2022 03:58

Привет, приятно знать об опечатке, я отредактировал свой пост. В настоящее время я использую PgAdmin v5.4 и Postgres 11.12. Нет параллельной записи. Я проверил журнал, и действительно, есть ошибка: ERROR: could not write to file "base/pgsql_tmp/pgsql_tmp9264.8256": No space left on device

Bil11 20.03.2022 12:17

Пожалуйста, уточните через правки, а не комментарии. Пожалуйста, не добавляйте «EDIT», просто отредактируйте для наилучшего представления. Но не редактируйте таким образом, чтобы сделать разумные опубликованные ответы недействительными. Пожалуйста, удалите и пометьте устаревшие комментарии. PS А какой вопрос вы пытаетесь задать? ПС минимальный воспроизводимый пример

philipxy 20.03.2022 20:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У вас заканчивается место на устройстве хранения. Освободить место на диске (или то, что вы используете в качестве хранилища) перед началом большого UPDATE. Удалить ненужные файлы (не связанные с базой данных). Или как-то уменьшить базу данных.

Простой VACUUMмощь выполняет свою работу. Или VACUUM FULL (блокирует одновременный доступ), чтобы агрессивно сжимать физическое хранилище. Если вы не можете позволить себе блокировку, рассмотрите один из неблокирующих инструментов сообщества. Видеть:

VACUUM FULL предпочтительно нет в sirene_eta (целевой таблице), которая в любом случае будет повторно использовать мертвые кортежи в UPDATE (после простого VACUUM). И убедитесь, что VACUUM не заблокирован длительной транзакцией. Видеть:

Что бы вы ни делали, если вы не ожидаете, что целевые строки все действительно изменятся, добавьте условие WHERE для фильтрации пустых обновлений (за полную стоимость!)

UPDATE sirene_eta eta
SET    longitude = geo.x
     , latitude  = geo.y
FROM   sirene_geo geo
WHERE  eta.siret = geo.siret
AND   (eta.longitude IS DISTINCT FROM geo.x  -- !
    OR eta.latitude  IS DISTINCT FROM geo.y)

Может даже решить вашу проблему, сократив объем работы (значительно). (Оказывается, это не в вашем случае.

Видеть:

Спасибо за совет, но, к сожалению, я хочу обновить все строки, чтобы это не изменило мою проблему.

Bil11 20.03.2022 12:20

Другие вопросы по теме