Доброго дня всем заинтересованным в теме. Пару дней назад столкнулся я с одной настолько неочевидной и вместе с тем опасной особенностью выполнения SQL в Teradata, что не мог не поделиться. Хотя допускаю, что post mortem поведение ее (Терадаты) выглядит по-своему логичным, но все же для тех, кто не специализируется конкретно на Teradata и при этом много работает с данными в разных типах хранилищ, подобное поведение является первоклассной расческой ловушкой, и мне пока не удалось найти другую БД, в которой она есть.

Постараюсь кратко.

Представим, что у нас есть огромная таблица с критичными данными:

select * from pcast.huge_table

ID

VALUE

0

zero

1

one

2

two

3

three

4

four

5

five

6

six

7

seven

8

eight

9

nine

777

too much

Также есть небольшая таблица со списком ключей, которые требуется удалить из большой критичной таблицы:

select * from pcast.small_table

ID

VALUE

777

Boss asked to remove this key from huge table

Удалим данные из большой таблицы по списку ключей, содержащихся в в малой:

delete 
from pcast.huge_table ht 
where ht.id in 
      (select ht.id 
       from pcast.small_table st)

Кто читает эту строку и уже видит ошибку, тому большой респект.

Кто не увидел и выполнил, тому привет ) Вы удалили ВСЕ данные из таблицы. Бегите за бэкапом, если сделали коммит. Казалось бы, подзапрос не имеет смысла, но не для Терадаты. В любой другой системе подобный скрипт упал бы с ошибкой вроде "не найдено поле ht.id в подзапросе" :

MySQL:

Databricks:

Databricks
Databricks

Но Терадата поступает по-своему. Ниже explain delete для такого запроса. Выделена самая интересная строка:

Как видим, ht.id - в рамках всего запроса для Терадаты есть поле известное, потому оно найдено, и это то же самое поле, с которым идет сравнение. Таким образом, условие where раносильно 1=1, delete срабатывает весьма успешно, и горе тому, кто не оценил Updated rows:

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

Будьте внимательны и осторожны!

Комментарии (0)