Понимание блокировок SQL Server по запросам SELECT

Мне интересно какая польза от использования SELECT WITH (NOLOCK) в таблице, если единственные другие запросы, влияющие на эту таблицу, SELECT запросы.

Как это обрабатывается SQL Server? Был бы SELECT запросить блок другой SELECT запрос?

Я использую SQL Server 2012 и Linq-to-SQL DataContext,

(РЕДАКТИРОВАТЬ)

О производительности:

  • Будет 2-й SELECT придется ждать 1-го SELECT закончить, если используется заблокированный SELECT?
  • По сравнению с SELECT WITH (NOLOCK)?

6 ответов

Решение

SELECT в SQL Server поместит общую блокировку на строку таблицы - и второй SELECT также потребуется общая блокировка, и они совместимы друг с другом.

Так что никто SELECT не может заблокировать другого SELECT,

Что за WITH (NOLOCK) Подсказка запроса используется для того, чтобы иметь возможность прочитать данные, которые находятся в процессе вставки (другим соединением) и которые еще не были зафиксированы.

Без подсказки запроса SELECT может быть заблокирован чтением таблицы постоянным INSERT (или же UPDATE) оператор, который устанавливает монопольную блокировку строк (или, возможно, всей таблицы), пока транзакция этой операции не будет зафиксирована (или откатана).

Проблема WITH (NOLOCK) Подсказка: вы можете читать строки данных, которые вообще не будут вставлены, в конце (если INSERT транзакция откатывается) - поэтому в вашем отчете, например, могут отображаться данные, которые в действительности никогда не передавались в базу данных.

Есть еще один полезный совет: WITH (READPAST), Это инструктирует SELECT Команда просто пропустить все строки, которые она пытается прочитать и которые заблокированы исключительно. SELECT не будет блокировать и не будет читать "грязные" незафиксированные данные, но может пропустить некоторые строки, например, не отобразит все ваши строки в таблице.

На производительности вы продолжаете фокусироваться на выборе.
Shared не блокирует чтения.
Обновление блоков общих блокировок.
Если у вас есть сотни общих блокировок, потребуется некоторое время, чтобы получить эксклюзивную блокировку, так как она должна подождать, пока общие блокировки будут сняты.

По умолчанию выбор (чтение) принимает общую блокировку.
Общие (S) блокировки позволяют параллельным транзакциям читать (SELECT) ресурс.
Общая блокировка как не влияет на другие выборки (1 или 1000).

Разница заключается в том, как nolock по сравнению с разделяемой блокировкой обновляет или вставляет операцию.

Никакие другие транзакции не могут изменять данные, пока на ресурсе существуют общие (S) блокировки.

Общая блокировка блокирует обновление!
Но nolock не блокирует обновление.

Это может оказать огромное влияние на производительность обновлений. Это также влияет на вставки.

Грязное чтение (нолок) просто звучит грязно. Вы никогда не собираетесь получать частичные данные. Если обновление меняет Джона на Салли, вы никогда не получите Джолли.

Я часто использую общие блокировки для параллелизма. Данные устаревают, как только они прочитаны. Чтение Джона, которое меняется на Салли в следующую миллисекунду, является устаревшими данными. Чтение Салли, возвращаемое Джоном в следующую миллисекунду, является устаревшими данными. Это на миллисекундном уровне. У меня есть загрузчик данных, который запускается 20 часов, если пользователи берут общие блокировки, и 4 часа запускают, если пользователи не берут блокировку. В этом случае общие блокировки приводят к устареванию данных на 16 часов.

Не используйте nolocks неправильно. Но у них есть место. Если вы собираетесь вырезать чек, когда байт установлен в 1, а затем установите его в 2, когда чек обрезан - не время для ноллока.

Я должен добавить важный комментарий. Все упоминают, что NOLOCKчитает только грязные данные. Это не точно. Также возможно, что вы получите одну и ту же строку дважды или вся строка будет пропущена во время чтения. Причина в том, что вы можете запросить некоторые данные в то же время, когда SQL Server выполняет повторную балансировку b-дерева.

Проверьте другие темы

/questions/45944273/chto-takoe-s-nolock-v-sql-server/45944322#45944322

http://www.sqlmag.com/article/sql-server/quaere-verum-clustered-index-scans-part-iii.aspx)

С подсказкой NOLOCK (или установив уровень изоляции сеанса READ UNCOMMITTED) вы сообщаете SQL Server, что не ожидаете согласованности, поэтому никаких гарантий нет. Имейте в виду, что "противоречивые данные" не только означают, что вы можете увидеть незафиксированные изменения, которые впоследствии были откатаны, или изменения данных в промежуточном состоянии транзакции. Это также означает, что в простом запросе, который сканирует все данные таблицы / индекса, SQL Server может потерять позицию сканирования или получить одну и ту же строку дважды.

В моей работе у нас очень большая система, которая работает на многих ПК одновременно, с очень большими таблицами с сотнями тысяч строк, а иногда и миллионами строк.

Когда вы делаете SELECT для очень большой таблицы, скажем, вы хотите знать каждую транзакцию, которую пользователь совершил за последние 10 лет, а первичный ключ таблицы не построен эффективным образом, запрос может занять несколько минут. бежать.

Затем наше приложение может работать на многих компьютерах пользователя одновременно, обращаясь к одной и той же базе данных. Поэтому, если кто-то пытается вставить в таблицу, которую читает другой SELECT (на страницах, которые пытается прочитать SQL), тогда может произойти LOCK, и две транзакции блокируют друг друга.

Мы должны были добавить "NO LOCK" в нашу инструкцию SELECT, потому что это был огромный SELECT для таблицы, которая используется многими пользователями одновременно, и у нас были LOCKS все время.

Я не знаю, достаточно ли ясен мой пример? Это пример из реальной жизни.

SELECT WITH (NOLOCK) позволяет считывать незафиксированные данные, что эквивалентно READ UNCOMMITTED уровень изоляции установлен в вашей базе данных. NOLOCK Ключевое слово обеспечивает более точный контроль, чем установка уровня изоляции для всей базы данных.

В Википедии есть полезная статья: Википедия: Изоляция (системы баз данных)

Это также подробно обсуждается в других статьях stackru.

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

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

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

Другие вопросы по тегам