SQL Server NOLOCK и объединяет
Справочная информация. У меня есть критически важный для пользователя запрос, который я хотел бы запустить, и я не забочусь о грязных чтениях.
Мой вопрос: Если я использую объединения, нужно ли мне также указывать подсказку NOLOCK?
Например; является:
SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b WITH (NOLOCK) ON a.ID = b.ID
Эквивалент:
SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b ON a.ID = b.ID
Или мне нужно указать подсказку (NOLOCK)
для соединения, чтобы убедиться, что я не блокирую связанную таблицу?
Ответы
Ответ 1
Я не буду рассматривать аргумент READ UNCOMMITTED
, просто ваш исходный вопрос.
Да, вам нужно WITH(NOLOCK)
для каждой таблицы соединения. Нет, ваши запросы не совпадают.
Попробуйте это упражнение. Начните транзакцию и вставьте строку в таблицу1 и таблицу2. Не совершайте и не откатывайте транзакцию. На этом этапе ваш первый запрос вернется успешно и включит незафиксированные строки; ваш второй запрос не будет возвращен, потому что table2 не имеет подсказки WITH(NOLOCK)
.
Ответ 2
Я был уверен, что вам нужно указать NOLOCK
для каждого JOIN
в запросе. Но мой опыт был ограничен SQL Server 2005.
Когда я посмотрел MSDN только для подтверждения, я не мог найти ничего определенного. Следующие утверждения, похоже, заставляют меня думать, что в 2008 году ваши два утверждения выше эквивалентны, хотя в 2005 году это не так:
[SQL Server 2008 R2]
Все подсказки блокировки распространяются на все таблицы и представления, которые доступны по плану запроса, включая таблицы и представления, на которые ссылаются в представлении. Кроме того, SQL Server выполняет соответствующие проверки согласованности блокировок.
[SQL Server 2005]
В SQL Server 2005 все подсказки блокировки распространяются на все таблицы и представления, на которые ссылаются в представлении. Кроме того, SQL Server выполняет соответствующие проверки согласованности блокировок.
Кроме того, укажите на заметку - и это относится как к 2005 году, так и к 2008 году:
Табличные подсказки игнорируются, если таблица не получает доступ по плану запроса. Это может быть вызвано тем, что оптимизатор решил не обращаться к таблице вообще, или потому, что вместо этого обращается к индексированному виду. В последнем случае доступ к индексированному представлению может быть предотвращен с помощью подсказки OPTION (EXPAND VIEWS)
.
Ответ 3
Ни. Вы устанавливаете уровень изоляции READ UNCOMMITTED
, который всегда лучше, чем давать индивидуальные подсказки блокировки. Или, еще лучше, если вам нужны детали, такие как согласованность, используйте изоляцию моментальных снимков.