Общие сведения о блокировках 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 56

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.

выбрать без блокировки-будут выбраны записи, которые могут / не могут быть вставлены. вы будете читать грязные данные.

например-допустим, транзакция вставляет 1000 строк, а затем терпит неудачу.

при выборе-вы получите 1000 строк.