Я видел операторы sql, использующие nolock и with(nolock), например -
select * from table1 nolock where column1 > 10
А ТАКЖЕ
select * from table1 with(nolock) where column1 > 10
Какое из приведенных утверждений верно и почему?
Я видел операторы sql, использующие nolock и with(nolock), например -
select * from table1 nolock where column1 > 10
А ТАКЖЕ
select * from table1 with(nolock) where column1 > 10
Какое из приведенных утверждений верно и почему?
Первый оператор ничего не блокирует, тогда как второй блокирует. Когда я только что проверил это на SQL Server 2005, в
select * from table1 nolock where column1 > 10 --INCORRECT
«nolock» стал в этом запросе псевдонимом table1.
select * from table1 with(nolock) where column1 > 10
выполняет желаемую функцию nolock. Скептически? В отдельном окне запустить
BEGIN TRANSACTION
UPDATE tabl1
set SomeColumn = 'x' + SomeColumn
чтобы заблокировать таблицу, а затем попробовать каждый оператор блокировки в отдельном окне. Первый будет висеть, ожидая снятия блокировки, а второй запустится сразу (и покажет "грязные данные"). Не забудьте оформить
ROLLBACK
когда вы закончите.
Список устаревших функций находится по адресу Устаревшие функции ядра СУБД в SQL Server 2008. :
- Указание NOLOCK или READUNCOMMITTED в предложении FROM инструкции UPDATE или DELETE.
- Указание табличных подсказок без использования ключевого слова WITH.
- Подсказка таблицы HOLDLOCK без круглых скобок
- Использование пробела в качестве разделителя между табличными подсказками.
- Косвенное применение таблицы намекает на вызов многооператорной функции с табличным значением (TVF) через представление.
Все они находятся в списке функций, которые иногда будут удалены после следующего выпуска SQL, а это означает, что они, вероятно, будут поддерживаться в выпуске enxt только при более низком уровне совместимости базы данных.
При этом мои 2c по этому вопросу таковы:
from table nolock
, и from table with(nolock)
неверны. Если вам нужны грязные чтения, используйте соответствующие уровни изоляции транзакций: set transaction isolation level read uncommitted
. Таким образом, используемый уровень изоляции явно указывается и управляется одной «ручкой», в отличие от того, чтобы распространяться по источнику и подчиняться всем причудам табличных подсказок (косвенное применение через представления и TVF и т. д.).Грязные чтения — это мерзость. В 99,99% случаев требуется снижение конкуренции, а не чтение незафиксированных данных. Конкуренция снижается за счет написания правильных запросов к хорошо разработанной схеме и, при необходимости, за счет развертывания изоляции моментальных снимков. Лучшее решение, которое почти всегда работает, за исключением нескольких крайних случаев, — это разрешить чтение зафиксированного снимка в базе данных и позволить движку творить чудеса:
ALTER DATABASE MyDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT ON
Затем удалите ВСЕ подсказки из выбора.
Оба они технически правильны, однако не использовать ключевое слово WITH объявлено устаревшим начиная с SQL 2005, так что привыкайте использовать ключевое слово WITH — короткий ответ, используйте ключевое слово WITH.
Используйте «С (БЕЗ БЛОКИРОВКИ)».
Оба синтаксически правильны.
NOLOCK станет псевдонимом для table1.
WITH (NOLOCK) часто используется как волшебный способ ускорить чтение базы данных, но я стараюсь по возможности избегать его использования.
Результирующий набор может содержать строки, которые еще не были зафиксированы и которые часто впоследствии откатываются.
Ошибка или набор результатов могут быть пустыми, содержать отсутствующие строки или отображать одну и ту же строку несколько раз.
Это связано с тем, что другие транзакции перемещают данные в то же время, когда вы их читаете.
READ COMMITTED добавляет дополнительную проблему, когда данные повреждаются в одном столбце, когда несколько пользователей одновременно изменяют одну и ту же ячейку.
Есть и другие побочные эффекты, которые приводят к потере увеличения скорости, которое вы надеялись получить в первую очередь.
Теперь вы знаете, никогда не используйте его снова.