Время прочтения: 2 мин.

При исполнении DML запросов (update, insert, delete) СУБД ограничивает доступность данных для других процессов, блокируя строки, до завершения транзакции. Эта особенность приводит к снижению производительности при большом количестве запросов и одним и тем же данным. Из-за этого происходит «тупиковая ситуация» БД, а именно 2 запроса обращаются к идентичным таблицам.

Hint nolock:

  • позволяет SQL считывать строки таблиц, исключая блокирование остальными запросами;
  • может повысить производительность и вводит возможность «Грязного чтения» (Dirty read). Dirty read позволяет считывать данные без учета действующих запросов и наложенных блокировок на таблицы.

Однако при использовании «грязного чтения» присутствуют как позитивные, так и негативные моменты.

Из положительных сторон можно отметить повышение производительности (пример ниже).

Мы имеем таблицу [TB54_SANDBOX].[dbo].[test] в которой ровно 10 000 000 записей.

Запускаем запрос на выборку количества записей в таблице:

Получаем время отработки запроса в 1 сек.

А теперь, перед запуском запроса, в параллельной вкладке, запускаем update:

В результате видим, что ко времени исполнения запроса на выбор строк (select) прибавилось время на update таблицы.

Пишем «nolock» и видим совершенно другое время на отработку:

Из минусов использования nolock при параллельном обновлении таблицы запрос может возвращать неверные результаты, а именно:

  1. видеть строки дважды;
  2. пропустить строки;
  3. видеть данные, которые не были зафиксированы;
  4. запрос может быть завершен с ошибкой (невозможно продолжить сканирование без блокировки из-за перемещения данных).

Исправить данные недостатки довольно просто:

  1. создать индекс на таблице;
  2. использовать другой уровень изоляции.