Таблица 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
подсказка для этой таблицы.