Поврежденная таблица базы данных с неверным запросом: что он сделал и откатится? - PullRequest
4 голосов
/ 16 июня 2011

Я сделал ошибку при запуске того, что должно было быть быстрым обновлением для моей таблицы фактов (200M строк) с этим:

update dbo.primary_fact
   set count_of_loan_obligors = o.n              
  from dbo.staging_fact f  
       -- notice that this is not the same table as the one in the update clause
       inner join ##Obligor_Count o
       on (f.time_dimension_id = o.time_dimension_id
           and f.account_dimension_id = o.account_dimension_id)

Это должно было быть:

  from dbo.primary_fact f

Правильно сформированное обновление, подобное этому (1 день, 87 тыс. Учетных записей), обычно заканчивается через минуту или 2. После 12 минут работы я подумал, что так долго, и заметил мою ошибку.

Я отменил запрос в SQL Server Management Studio, который, как я понимаю, откатит все ужасы, которые я вызвал (кто-то может подтвердить?)

Но мой главный вопрос: что делает неправильно сформированный запрос?


Обновление: Действие отмены наконец завершено, через час и 39 минут. Администраторы баз данных были слишком медленными в убийстве - также хорошо.

Правильно сформированное обновление завершено за 8 секунд.

Второе обновление: Не было значений, установленных из исходного (неисправного) обновления после успешного порядка отмены в SSMS. Я бы интерпретировал это как означающее, что все ожидающие обновления были отменены.

Ответы [ 3 ]

5 голосов
/ 16 июня 2011

Но мой большой вопрос: что делает неправильно сформированный запрос?

Он обновит dbo.primary_fact.count_of_loan_obligors с одинаковым значением для всех строк.Значение будет некоторым значением из ##Obligor_Count.n.Трудно понять, какое значение это будет.

Вот небольшой тест, который в основном делает то, что вы сделали:

declare @T1 table (ID int)
declare @T2 table (ID int)

insert into @T1 values (0)
insert into @T1 values (0)

insert into @T2 values (2)
insert into @T2 values (1)

update @T1
set ID = T2.ID
from @T2 as T2

select *
from @T1

Результат:

ID
2
2

В этом случае @T1 обновляется первой строкой в ​​@T2.

3 голосов
/ 16 июня 2011

Ну, во-первых, похоже, что вы, возможно, просто повторно запустите свой запрос с правильным предложением from вместо таблицы staging_fact, и он перезапишет все сделанные вами буферы.Это хорошая новость и радость работы с таблицами фактов.

Плохая новость заключается в том, что из моего опыта SSMS ничего не откатывает, если вы на самом деле не выполняете это в транзакции, поэтому ваши данные, вероятно,прямо сейчас.

Надеюсь, вам понравились последние 12 минут вашей жизни, потому что вы получите удовольствие от повторения.

2 голосов
/ 16 июня 2011

Я беспокоюсь о том, что ни одна из версий не принесет ничего хорошего, потому что в обеих версиях отсутствует предложение WHERE, связывающее обновляемую таблицу с источником новых значений (f inner join o). Я ожидаю, что строка WHERE primary_fact.time_dimension_id=f.time_dimension_id AND primary_fact.account_dimension_id=f.account_dimension_id была пропущена при копировании / вставке.

Пока в ссылочных таблицах есть столбцы этих имен, объединение f и o будет выполняться очень хорошо. Затем эти значения будут использоваться для обновления primary_fact, либо с помощью предложения WHERE, либо каким-либо образом, которого я не знаю. Синтаксис UPDATE / FROM не является стандартным SQL, но он широко поддерживается. Может быть, SQL SERVER даже добавляет в предложение WHERE по умолчанию. Postgresql не делает.

...