Таблица SQL Server блокируется в длинном запросе - Решение: NoLock?

Отчет в моем приложении выполняет запрос, который требует от 5 до 15 секунд (ограничено числом строк, которые будут возвращены). Запрос имеет 8 соединений почти со всеми основными таблицами моего приложения (клиенты, продажи, единицы и т. Д.).

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

Решение от друга состоит в том, чтобы иметь каждое соединение в запросе, что не является обязательным, чтобы иметь 100% правильные данные (грязное чтение), с NoLock, так что только 1 из этих 8 таблиц будет заблокирована полностью. Это хорошее решение? Для отчета, в котором 99% данных поступили из одной таблицы, разблокируйте менее первичные таблицы?

3 ответа

Решение

Попробуйте взглянуть на READ COMMITTED SNAPSHOT, а не на NOLOCK. Это означает, что данные могут быть "старыми", но никогда не будут грязными.

NOLOCK значит не ставить замки вообще.

Ваш запрос может вернуть части данных, как и раньше UPDATE и порции после UPDATE в одном запросе.

Мол, дебет без кредита и тому подобное.

Например, я только что выполнил этот запрос на большой таблице:

SELECT  SUM(LEN(name))
FROM    master WITH (NOLOCK)
OPTION (MAXDOP 1)

---
18874367

Все nameдлина 1,

Затем я перезапускаю его и в середине запроса обновляю таблицу:

UPDATE  master
SET     name = 'tt'
WHERE   id <= 10000

SELECT  SUM(LEN(name))
FROM    master WITH (NOLOCK)
OPTION (MAXDOP 1)

---
18874944

Как мы видим, этот запрос заметил 577 строки как обновленные (длина 2), все остальные строки не обновлены (длина 1).

SELECT  SUM(LEN(name))
FROM    master WITH (NOLOCK)
OPTION (MAXDOP 1)

---
18884367

И этот запрос, запускаемый сразу после завершения предыдущего, видит все обновления.

Это нормально, если вы очень сильно подчеркиваете эту фразу:

что не является обязательным, чтобы иметь 100% правильные данные (грязное чтение)

Таким образом, вы, вероятно, не хотите добавлять подсказку nolock к своей таблице продаж, но ваша таблица клиентов (которая, вероятно, видит меньше изменений) может быть в порядке. Даже там вы, вероятно, не используете столько записей о клиентах в одном запросе, но если один из них изменится, это может стать большой проблемой. Таким образом, вы можете указать rowlock подсказка для этой таблицы.

Другие вопросы по тегам