Эффект подсказки NOLOCK в операторах SELECT

Думаю, настоящий вопрос:

Если меня не интересуют грязные чтения, добавление подсказки с (NOLOCK) к оператору SELECT повлияет на производительность:

  1. текущий оператор SELECT
  2. другие транзакции против данной таблицы

Пример:

Select * 
from aTable with (NOLOCK)

Эти ответы ТАК и DBA немного яснее относительно того, что на самом деле происходит.

Trisped 21.01.2016 23:55
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
204
1
342 133
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Это будет быстрее, потому что не нужно ждать блокировки

Насколько быстрее? Не могли бы вы предоставить какие-либо цифры улучшения скорости?

Eugeniu Torica 16.04.2010 15:51

«Сколько» зависит от того, что вы конкретно делаете со своими данными и как долго вам обычно приходится ждать получения блокировки.

StingyJack 19.04.2010 20:40

Единственный правильный тест - это тот, который вы создаете и запускаете самостоятельно. То, что вам все говорят, ничем не хуже, чем «чек по почте». Я много раз доказывал ошибочность многих мифов и предположений, проводя собственные тесты.

TravisO 20.08.2013 23:10

^ @TravisO - совершенно правильно. Несколько раз у меня NOLOCK выполнялся медленнее. Не совсем уверен, почему, но я использую это при устранении неполадок, и я не хочу отрицательно (чрезмерно) влиять на производство

StingyJack 29.06.2017 22:52
Ответ принят как подходящий

1) да, выбор с NOLOCK завершится быстрее, чем обычный выбор.

2) да, выбор с помощью NOLOCK позволит другим запросам к затронутой таблице выполняться быстрее, чем при обычном выборе.

Почему это могло быть?

NOLOCK обычно (в зависимости от вашего механизма БД) означает предоставление мне ваших данных, и меня не волнует, в каком состоянии они находятся, и не беспокоиться о том, чтобы держать их неподвижно, пока вы читаете из них. Это все одновременно быстрее, менее ресурсоемко и очень-очень опасно.

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

У вас действительно нет возможности узнать, в каком состоянии находятся данные.

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

Всегда используйте подсказку NOLOCK с большой осторожностью и относитесь к любым возвращаемым данным с подозрением.

Спасибо. Это то, что я предполагал, но меня спросил об этом коллега, и мое первоначальное исследование заставило меня усомниться в себе. В документации SQLServer 2005 говорится, что NOLOCK является схемой блокировки по умолчанию для всех операторов select! Тогда я предполагаю, что мои намеки будут излишними в ...

Bob Probst 17.10.2008 00:55

... 2005 год и не имеет никакого эффекта. Прямо сейчас у нас работает 2000 (спасибо нашему поставщику), и в документации нет подобного заявления.

Bob Probst 17.10.2008 00:57

Вашему другу нужно прочитать документацию. Подсказка по таблице (Transact-SQL) msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx

Pittsburgh DBA 17.10.2008 01:48

Примечание: если бы это было правдой, это был бы абсолютный хаос.

Pittsburgh DBA 17.10.2008 01:53

Пункты 1 и 2 должны быть ограничены 1) «... когда в таблице ожидается действие вставки / обновления / удаления». и 2) «... разрешит запросы вставить / обновить / удалить против ...». Я бы (личное предпочтение) изменил экземпляры «быстрее» на «раньше», поскольку разница заключается в ожидании завершения другого процесса.

Trisped 21.01.2016 23:40

NOLOCK делает большинство операторов SELECT быстрее из-за отсутствия общих блокировок. Кроме того, отсутствие блокировки означает, что ваш SELECT не будет препятствовать писателям.

NOLOCK функционально эквивалентен уровню изоляции READ UNCOMMITTED. Основное отличие состоит в том, что вы можете использовать NOLOCK для одних таблиц, но не для других, если захотите. Если вы планируете использовать NOLOCK для всех таблиц в сложном запросе, то использовать SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED проще, потому что вам не нужно применять подсказку к каждой таблице.

Здесь представлена ​​информация обо всех имеющихся в вашем распоряжении уровнях изоляции, а также табличные подсказки.

УСТАНОВИТЬ УРОВЕНЬ ИЗОЛЯЦИИ СДЕЛКИ

Подсказка по таблице (Transact-SQL)

Согласен, но не полностью; Важно отметить, что подсказка NO LOCK / READ UNCOMMITTED на самом деле не улучшает скорость запроса, но, более того, заставляет его отображаться быстрее, потому что ему не нужно ждать завершения предыдущих запросов. Так что на самом деле запрос ВИДЕТСЯ быстрее, а не быстрее (я думаю).

Möoz 07.08.2013 06:00

@BorhanMooz Что ж, есть экономия от того, что не нужно запрашивать блокировки у диспетчера блокировок. Даже если нет других ожидающих запросов, это требует затрат и накладных расходов на память.

Pittsburgh DBA 07.08.2013 23:09

Я обсуждал это с некоторыми из моих коллег по работе. Насколько я понимаю, запрос, использующий подсказку WITH (NOLOCK), по-прежнему требует, чтобы была достигнута общая блокировка схемы (mssqltips.com/sqlservertip/2470/…).

Möoz 08.08.2013 05:11

Да, но не тысячи общих блокировок страниц или экстентов. Блокировка схемы - это ОДНА блокировка, а не ТЫСЯЧИ. Если мы хотим быть педантичными, мы можем продолжить обсуждение этого вопроса, но да, накладные расходы на блокировку будут минимальными. Экономия значительная. Посчитайте это: msdn.microsoft.com/en-us/library/aa337559(v=sql.100).aspx

Pittsburgh DBA 08.08.2013 07:22

В дополнение к тому, что было сказано выше, вы должны быть очень осведомлены, что nolock фактически накладывает риск того, что вы нет получите строки, которые были зафиксированы до по вашему выбору.

См. http://blogs.msdn.com/sqlcat/archive/2007/02/01/previously-committed-rows-might-be-missed-if-nolock-hint-is-used.aspx

  • Ответ - да, если запрос выполняется несколько раз одновременно, потому что каждой транзакции не нужно ждать завершения других. Однако, если запрос выполняется один раз сам по себе, ответ - Нет.

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

Будьте осторожны, чтобы Только использовал WITH (NOLOCK) в операторах SELECT для таблиц с кластеризованным индексом.

WITH (NOLOCK) часто используется как волшебный способ ускорить транзакции чтения базы данных.

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

Если WITH (NOLOCK) применяется к таблице с некластеризованным индексом, то индексы строк могут быть изменены другими транзакциями, поскольку данные строки передаются в таблицу результатов. Это означает, что в наборе результатов могут отсутствовать строки или одна и та же строка может отображаться несколько раз.

READ COMMITTED добавляет дополнительную проблему, когда данные повреждены в одном столбце, когда несколько пользователей изменяют одну и ту же ячейку одновременно.

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