2017-02-21 3 views
0

Мне нужно обновить около 300 строк в большой таблице (600 м строк), и я пытаюсь сделать это быстрее.Redshift UPDATE использует Seq Scan очень медленно

Запроса Я использую немного сложнее:

UPDATE my_table 
SET name = CASE WHEN (event_name in ('event_1', 'event_2', 'event_3')) 
THEN 'deleted' ELSE name END 
WHERE uid IN ('id_1', 'id_2') 

Я пытаюсь использовать EXPLAIN на этом запросе, и я получаю:

XN Seq Scan on my_table (cost=0.00..103935.76 rows=4326 width=9838) 
    Filter: (((uid)::text = 'id_1'::text) OR ((uid)::text = 'id_2'::text)) 

У меня есть перемежающаяся SortKey и UID является один столбцов, включенных в этот файл. Причина, по которой запрос выглядит так, заключается в том, что в реальном контексте количество столбцов в SET (вместе с именем) может меняться, но оно, вероятно, будет не более 10. Основная идея заключается в том, что я не хотите перекрестное соединение (правила обновления относятся к столбцам, я не хочу их смешивать). К примеру, в будущем будет запрос типа:

UPDATE my_table 
SET name = CASE WHEN (event_name in ("event_1", "event_2", "event_3")) THEN 'deleted' ELSE name END, 
address = CASE WHEN (event_name in ("event_1", "event_4")) THEN 'deleted' ELSE address END 
WHERE uid IN ("id_1", "id_2") 

Во всяком случае, на первый запрос, он работает в течение очень долгого времени (около 45 минут) и занимает 100% CPU.

Я попытался проверить еще проще запрос:

explain UPDATE my_table SET name = 'deleted' WHERE uid IN ('id_1', 'id_2') 
XN Seq Scan on my_table (cost=0.00..103816.80 rows=4326 width=9821) 
    Filter: (((uid)::text = 'id_1'::text) OR ((uid)::text = 'id_2'::text)) 

Я не знаю, что еще я могу добавить к вопросу, чтобы сделать его более ясным, был бы рад услышать любые советы.

+0

Фактический запрос должен быть совершенно иным, поскольку ключевое слово WHERE в операторе CASE приведет к ошибке. Есть ли там суб-выбор? Кроме того, что такое distkey на столе? – systemjack

+0

Ах, действительно, исправил это сейчас. –

+0

Ваш запрос выглядит хорошо для меня. Мне не повезло с чередующимися ключами сортировки. Фильтрация на столбце, не являющемся частью ключа сортировки, по-прежнему имеет около 10-кратное улучшение, используя составной ключ сортировки или чередующийся. Фильтрация в столбце sortkey должна быть еще лучше. Мы отказались от использования чередующихся ключей, пока Redshift не разобрал их. – systemjack

ответ

1

Вы пытались удалить ключ сортировки с чередованием и заменить его простым ключом сортировки на uid или сложным ключом сортировки с uid в качестве первого столбца?

Кроме того, имя uid заставляет меня думать, что вы можете использовать GUID/UUID в качестве значения. Я бы предположил, что это anti-pattern для значения id в Redshift и особенно для ключа сортировки.

Проблемы с GUID/UUID id:

  • Не происходит в предсказуемой последовательности
    • Часто вызывает полное последовательное сканирование
    • новые строки всегда нарушать Рода
  • Сжатие очень плохо
    • Требует больше места на диска для хранения
    • требуется больше данных для чтения при запросе
+0

Да, uid - это строка MongoId. Просто понял, что sortkey по крайней мере, скорее всего, не сработал, поскольку из 600-миллиметровых рядов было отсортировано только несколько миллионов. Возможно, это требует другого вопроса, но, возможно, вы могли бы предложить что-то: если таблица настолько велика, что пылесос занимает слишком много времени, а для глубокой копии требуется больше места на диске, чем доступно, что может быть другим способом переиндексации таблицы? –

+1

Это зависит от того, насколько велика таблица TBH. С поистине огромной таблицей можно было бы разделить ее на более мелкие таблицы, содержащие ограниченный набор данных (например, неделю или месяц) и представление «UNION ALL» над ними, чтобы заменить исходную таблицу. Вы не упоминали свой 'DISTSTYLE' - я бы попытался использовать' uid' в качестве ключа распределения с ключом сортировки в столбце timestamp. –

+0

Если у вас нет места, вы можете сделать инкрементный UNLOAD на S3, УДАЛИТЬ диапазон, который вы разгрузили, а затем КОПИРОВАТЬ с S3 обратно в новую таблицу. Кроме того, если у вас есть проблемы с пространством и вы еще не включили сжатие, это будет отличная возможность: http://docs.aws.amazon.com/redshift/latest/dg/t_Compressing_data_on_disk.html. – systemjack

0

обновления в красном смещении удалить, а затем вставить. Redshift по дизайну просто маркирует строки как удаленные и не удаляя их физически (строки-призраки). Явно вакуумное удаление только < имя_таблицы> требуется для освобождения места.

Seq. Сканирование влияет на эти строки призраков. Предложите выполнить команду над командой и проверить производительность запроса позже.

Смежные вопросы