Обновление столбца в Amazon Redshift с объединением для больших таблиц - PullRequest
0 голосов
/ 10 февраля 2020

У меня 500M строк с таблицей 30 столбцов (с столбцом идентификатора bigint), назовем его big_one. Кроме того, у меня есть еще одна таблица extra_one с тем же количеством строк и идентичным столбцом идентификатора, но двумя новыми столбцами с дополнительными данными, которые я хотел бы включить в первую таблицу. Я добавил два дополнительных столбца в первую таблицу и хочу обновить данные на основе объединения.

Запрос довольно прост:

update big_one set
    col1=extra_one.col1,
    col2=extra_one.col2
from extra_one
where big_one.id=extra_one.id;

Но во время выполнения использование дискового пространства значительно увеличилось до 100%. До старта у меня было 23,41% свободного места на 4 узлах (по 160 ГБ каждый, всего 640 ГБ). Таблица big_one изначально занимала около 18% пространства. Эти 23,41% указывают, что у меня было около 490 ГБ свободного дискового пространства для беспрепятственного выполнения обновлений. Но Redhisft думает по-другому.

disk space usage

Два новых столбца - это хеши md5 (поэтому они имеют длину 32 символа) (в идеале это должно занять до 16 ГБ пространство).

Резюме:

  1. У меня есть широкий стол big_one.

  2. Есть еще один стол extra_one (с 3 всего столбцов), с одинаковыми идентификаторами и количеством записей.

  3. Я добавил два новых столбца в big_one.

  4. Я хочу дополнить big_one с данными из extra_one. (в эти 2 новых столбца)

Q1: Какой-нибудь совет, как выполнить такие большие обновления?

Q2: Если я создам ПРОСМОТР, где объединю две таблицы и затем использую его, спасет ли меня меня от таких ситуаций с утечкой пространства? Как Redshift работает с VIEW (не материализовано) в таких случаях.

1 Ответ

1 голос
/ 11 февраля 2020

Не используйте UPDATE для большого количества строк.

При изменении строки в Amazon Redshift существующая строка помечается как Удалено , и добавляется новая строка к столу. Это будет эффективно удваивать размер таблицы и тратить много места на диске до тех пор, пока таблица не будет очищена. Это также очень медленно!

Вместо этого:

  • Создайте запрос, который JOINs две таблицы
  • Используйте запрос к заполните новую таблицу (см. ниже)
  • Удалите старую таблицу и переименуйте новую таблицу , чтобы она заменила исходную таблицу (или, обрежьте исходную таблицу и скопируйте данные обратно в него)

Вы можете использовать CREATE TABLE LIKE для создания новой пустой таблицы на основе существующей таблицы.

Из CREATE TABLE - Amazon Redshift :

LIKE parent_table [ { INCLUDING | EXCLUDING } DEFAULTS ]
Предложение, которое указывает существующую таблицу, из которой новая таблица автоматически копирует имена столбцов, типы данных и ограничения NOT NULL. Новая таблица и родительская таблица не связаны, и любые изменения, внесенные в родительскую таблицу, не применяются к новой таблице. Выражения по умолчанию для скопированных определений столбцов копируются, только если указано ВКЛЮЧЕНИЕ ПО УМОЛЧАНИЮ. Поведение по умолчанию заключается в исключении выражений по умолчанию, чтобы все столбцы новой таблицы имели нулевые значения по умолчанию.

Таблицы, созданные с помощью параметра LIKE, не наследуют ограничения первичного и внешнего ключей. Стиль распределения, ключи сортировки, свойства BACKUP и NULL наследуются таблицами LIKE, но их нельзя явно установить в операторе CREATE TABLE ... LIKE.

...