Общие сведения о блокировках SQL Server для запросов SELECT
мне интересно, какую пользу можно использовать SELECT WITH (NOLOCK)
на таблицу, если только другие запросы, влияющие на эту таблицу SELECT
запросы.
как это обрабатывается SQL Server? Бы SELECT
блок запроса другой SELECT
запрос?
Я использую SQL Server 2012 и Linq-to-SQL DataContext
.
(EDIT)
о работе :
- будет 2-й
SELECT
придется ждать 1-йSELECT
для завершения при использовании заблокированногоSELECT
? - и
SELECT WITH (NOLOCK)
?
спасибо.
6 ответов:
A
SELECT
в SQL Server разместим a общий замок в строке таблицы - и второйSELECT
также потребуется общая блокировка, и они совместимы друг с другом.никто
SELECT
не может блокировать другойSELECT
.какого
WITH (NOLOCK)
подсказка запроса используется для того, чтобы иметь возможность читать данные, которые находятся в процессе вставки (другим соединением), и которые еще не были зафиксированы.без этой подсказки запроса, a
SELECT
может быть заблокировано чтение таблицы текущимINSERT
(илиUPDATE
) заявление, которое помещает эксклюзивные блокировка строк (или, возможно, всей таблицы), пока транзакция этой операции не будет зафиксирована (или откат).проблема
WITH (NOLOCK)
подсказка: вы можете читать строки данных, которые не будут вставлены вообще, в конце концов (еслиINSERT
транзакция откатывается) - так что ваш, например, отчет может показать данные, которые никогда не были совершены в базу данных.есть еще один запрос подсказка, которая может быть полезна -
WITH (READPAST)
. Это инструктируетSELECT
команда просто пропустить любые строки, которые он пытается прочитать и которые заблокированы исключительно. ЭлементSELECT
не будет блокировать, и он не будет читать какие-либо "грязные" незафиксированные данные - но он может пропустить некоторые строки, например, не показывать все ваши строки в таблице.
по производительности вы продолжаете фокусироваться на select.
Shared не блокирует чтение.
Обновление блоков общей блокировки.
Если у вас есть сотни общих блокировок, потребуется некоторое время, чтобы получить эксклюзивную блокировку, поскольку она должна ждать, пока общие блокировки будут очищены.по умолчанию select (read) принимает общую блокировку.
Общие блокировки позволяют параллельным транзакциям читать (выбирать) ресурс.
Общая блокировка как не влияет на другие выбирает (1 или 1000).разница заключается в том, как nolock против общих эффектов блокировки обновляют или вставляют операцию.
никакие другие транзакции не могут изменять данные, пока на ресурсе существуют общие блокировки.
общая блокировка блокирует обновление!
Но nolock не блокирует обновление.Это может иметь огромное влияние на производительность обновления. Оно также вставки удара.
грязное чтение (nolock) просто звучит грязно. Вы никогда не получите частичное данные. Если обновление меняет Джона на Салли, вы никогда не будете веселиться.
Я использую общие блокировки много для параллелизма. Данные устаревают, как только их читают. Чтение Джона, которое меняется на Салли в следующую миллисекунду, - это устаревшие данные. Чтение Салли, которое откатывается Джоном в следующую миллисекунду, - это устаревшие данные. То есть на миллисекундном уровне. У меня есть dataloader, который занимает 20 часов для запуска, если пользователи принимают общие блокировки и 4 часа для запуска, пользователи не принимают блокировку. Общие блокировки в этом случае приводят к устареванию данных на 16 часов.
Не используйте nolocks неправильно. Но у них есть место. Если вы собираетесь вырезать чек, когда байт установлен в 1, а затем установить его в 2, когда чек вырезан - не время для nolock.
в моей работе у нас есть очень большая система, которая работает на многих ПК одновременно, с очень большими таблицами с сотнями тысяч строк, а иногда и многими миллионами строк.
когда вы делаете выбор на очень большой таблице, скажем, вы хотите знать каждую транзакцию, которую пользователь сделал за последние 10 лет, и первичный ключ таблицы не построен эффективным образом, запрос может занять несколько минут для запуска.
тогда наше приложение может быть запущено много ПК потребителя в то же время, получая доступ к такой же базе данных. Поэтому, если кто-то пытается вставить в таблицу, которую читает другой выбор (на страницах, которые пытается прочитать SQL), может произойти блокировка, и две транзакции блокируют друг друга.
нам пришлось добавить" no LOCK " в наш оператор SELECT, потому что это был огромный выбор на таблице, которая используется много многими пользователями одновременно, и у нас были блокировки все время.
Я не знаю, достаточно ли ясен мой пример? Это реальный пример из жизни.
Я должен добавить важный комментарий. Все говорят, что
NOLOCK
читает только "грязные" данные. Это не совсем точно. Также возможно, что вы получите одну и ту же строку дважды или вся строка будет пропущена во время чтения. Причина в том, что вы можете запросить некоторые данные в то же время, когда SQL Server повторно балансирует b-дерево.проверить другой threads
https://stackoverflow.com/a/5469238/2108874
http://www.sqlmag.com/article/sql-server/quaere-verum-clustered-index-scans-part-iii.aspx)
С помощью подсказки NOLOCK (или установки уровня изоляции сеанса для чтения UNCOMMITTED) вы сообщаете SQL Server, что не ожидаете согласованности, поэтому нет никаких гарантий. Имейте в виду, что "несогласованные данные" не только означают, что вы можете увидеть незафиксированные изменения, которые впоследствии были отменены или изменения данных в промежуточном состоянии транзакции. это также означает, что в простом запросе, который сканирует все данные таблицы/индекса SQL Server может потерять позицию сканирования, или вы можете получить одну и ту же строку дважды.
The
SELECT WITH (NOLOCK)
позволяет считывать незафиксированные данные, что эквивалентно наличиюREAD UNCOMMITTED
уровень изоляции, установленный в базе данных. ЭлементNOLOCK
ключевое слово позволяет более мелкозернистый контроль, чем установка уровня изоляции на всей базе данных.в Википедии есть полезная статья: Википедия: изоляция (системы баз данных)
Это также подробно обсуждается в других статьях stackoverflow.