Но ведь NOLOCK это хорошо, когда данные не меняются, правильно?

Пересказ статьи Brent Ozar. But NOLOCK Is Okay When The Data Isn’t Changing, Right?

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

Но я запрашиваю данные, которые не изменяются — конечно, ДРУГИЕ строки в таблице изменяются, но не те строки, которые мне нужны. Разве не правильно использовать NOLOCK, если я запрашиваю неизменные строки?

Нет. Даже близко нет. Возьмите любую базу данных Stack Overflow и начните с запроса из последнего поста — только теперь мы изменим его таким образом, чтобы обновлялись одни пользователи, а запрашивались другие.

Часто встречающийся ник (DisplayName) — Alex. В одном окне я буду подсчитывать число Алексов:

SELECT COUNT(*) 
FROM dbo.Users WITH (NOLOCK)
WHERE DisplayName = 'alex';
GO 20

А в другом окне я буду менять местонахождение и веб-сайт для всех ЗА ИСКЛЮЧЕНИЕМ Алексов, которых я не собираюсь трогать:

BEGIN TRAN
UPDATE dbo.Users
  SET Location = N'The Derek Zoolander School for Kids Who Can''t Read Good and Want to Do Other Stuff Good Too',
      WebsiteUrl = N'https://www.youtube.com/watch?v=NQ-8IuUkJJc'
  WHERE DisplayName <> 'alex';
GO

Полюбуйтесь на катастрофу.
Похоже, что число пользователей с именем Alex меняется; и это НЕСМОТРЯ НА ТО, ЧТО Я НЕ ОБНОВЛЯЮ ЭТИ СТРОКИ! Причина: строки с именем Alex могут перемещаться в результате изменений, происходящих с другими строками.

Что еще тут можно сказать; при NOLOCK вы можете:

  • Увидеть строки дважды.
  • Вообще пропустить строки.
  • Увидеть данные, которые никогда не будут зафиксированы.
  • Еще ваш запрос может отвалиться с ошибкой.

Если вы в состоянии разобраться с этим, отлично — NOLOCK для вас. Если нет, самое время рассмотреть другие способы получить требуемую производительность, сохраняя точность данных, которую ожидают получить ваши пользователи.

Добавить комментарий