Думаю, настоящий вопрос:
Если меня не интересуют грязные чтения, добавление подсказки с (NOLOCK) к оператору SELECT повлияет на производительность:
Пример:
Select *
from aTable with (NOLOCK)


Это будет быстрее, потому что не нужно ждать блокировки
Насколько быстрее? Не могли бы вы предоставить какие-либо цифры улучшения скорости?
«Сколько» зависит от того, что вы конкретно делаете со своими данными и как долго вам обычно приходится ждать получения блокировки.
Единственный правильный тест - это тот, который вы создаете и запускаете самостоятельно. То, что вам все говорят, ничем не хуже, чем «чек по почте». Я много раз доказывал ошибочность многих мифов и предположений, проводя собственные тесты.
^ @TravisO - совершенно правильно. Несколько раз у меня NOLOCK выполнялся медленнее. Не совсем уверен, почему, но я использую это при устранении неполадок, и я не хочу отрицательно (чрезмерно) влиять на производство
1) да, выбор с NOLOCK завершится быстрее, чем обычный выбор.
2) да, выбор с помощью NOLOCK позволит другим запросам к затронутой таблице выполняться быстрее, чем при обычном выборе.
Почему это могло быть?
NOLOCK обычно (в зависимости от вашего механизма БД) означает предоставление мне ваших данных, и меня не волнует, в каком состоянии они находятся, и не беспокоиться о том, чтобы держать их неподвижно, пока вы читаете из них. Это все одновременно быстрее, менее ресурсоемко и очень-очень опасно.
Вы должны быть предупреждены о том, что никогда не выполняйте обновление или выполнение чего-либо критически важного для системы или когда требуется абсолютная корректность с использованием данных, полученных в результате чтения NOLOCK. Вполне возможно, что эти данные содержат строки, которые были удалены во время выполнения запроса или которые были удалены в других сеансах, которые еще не были завершены. Возможно, в эти данные входят строки, которые были частично обновлены. Возможно, эти данные содержат записи, нарушающие ограничения внешнего ключа. Возможно, эти данные не включают строки, которые были добавлены в таблицу, но еще не зафиксированы.
У вас действительно нет возможности узнать, в каком состоянии находятся данные.
Если вы пытаетесь получить такие вещи, как количество строк или другие сводные данные, где допустима некоторая погрешность, то NOLOCK - хороший способ повысить производительность для этих запросов и избежать их негативного влияния на производительность базы данных.
Всегда используйте подсказку NOLOCK с большой осторожностью и относитесь к любым возвращаемым данным с подозрением.
Спасибо. Это то, что я предполагал, но меня спросил об этом коллега, и мое первоначальное исследование заставило меня усомниться в себе. В документации SQLServer 2005 говорится, что NOLOCK является схемой блокировки по умолчанию для всех операторов select! Тогда я предполагаю, что мои намеки будут излишними в ...
... 2005 год и не имеет никакого эффекта. Прямо сейчас у нас работает 2000 (спасибо нашему поставщику), и в документации нет подобного заявления.
Вашему другу нужно прочитать документацию. Подсказка по таблице (Transact-SQL) msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx
Примечание: если бы это было правдой, это был бы абсолютный хаос.
Пункты 1 и 2 должны быть ограничены 1) «... когда в таблице ожидается действие вставки / обновления / удаления». и 2) «... разрешит запросы вставить / обновить / удалить против ...». Я бы (личное предпочтение) изменил экземпляры «быстрее» на «раньше», поскольку разница заключается в ожидании завершения другого процесса.
NOLOCK делает большинство операторов SELECT быстрее из-за отсутствия общих блокировок. Кроме того, отсутствие блокировки означает, что ваш SELECT не будет препятствовать писателям.
NOLOCK функционально эквивалентен уровню изоляции READ UNCOMMITTED. Основное отличие состоит в том, что вы можете использовать NOLOCK для одних таблиц, но не для других, если захотите. Если вы планируете использовать NOLOCK для всех таблиц в сложном запросе, то использовать SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED проще, потому что вам не нужно применять подсказку к каждой таблице.
Здесь представлена информация обо всех имеющихся в вашем распоряжении уровнях изоляции, а также табличные подсказки.
УСТАНОВИТЬ УРОВЕНЬ ИЗОЛЯЦИИ СДЕЛКИ
Подсказка по таблице (Transact-SQL)
Согласен, но не полностью; Важно отметить, что подсказка NO LOCK / READ UNCOMMITTED на самом деле не улучшает скорость запроса, но, более того, заставляет его отображаться быстрее, потому что ему не нужно ждать завершения предыдущих запросов. Так что на самом деле запрос ВИДЕТСЯ быстрее, а не быстрее (я думаю).
@BorhanMooz Что ж, есть экономия от того, что не нужно запрашивать блокировки у диспетчера блокировок. Даже если нет других ожидающих запросов, это требует затрат и накладных расходов на память.
Я обсуждал это с некоторыми из моих коллег по работе. Насколько я понимаю, запрос, использующий подсказку WITH (NOLOCK), по-прежнему требует, чтобы была достигнута общая блокировка схемы (mssqltips.com/sqlservertip/2470/…).
Да, но не тысячи общих блокировок страниц или экстентов. Блокировка схемы - это ОДНА блокировка, а не ТЫСЯЧИ. Если мы хотим быть педантичными, мы можем продолжить обсуждение этого вопроса, но да, накладные расходы на блокировку будут минимальными. Экономия значительная. Посчитайте это: msdn.microsoft.com/en-us/library/aa337559(v=sql.100).aspx
В дополнение к тому, что было сказано выше, вы должны быть очень осведомлены, что nolock фактически накладывает риск того, что вы нет получите строки, которые были зафиксированы до по вашему выбору.
Ответ - да, если запрос выполняется несколько раз одновременно, потому что каждой транзакции не нужно ждать завершения других. Однако, если запрос выполняется один раз сам по себе, ответ - Нет.
да. Существует значительная вероятность того, что осторожное использование WITH (NOLOCK) ускорит вашу базу данных в целом. Это означает, что другим транзакциям не придется ждать завершения этого оператора SELECT, но, с другой стороны, другие транзакции будут замедляться, поскольку теперь они делят свое время обработки с новой транзакцией.
Будьте осторожны, чтобы Только использовал WITH (NOLOCK) в операторах SELECT для таблиц с кластеризованным индексом.
WITH (NOLOCK) часто используется как волшебный способ ускорить транзакции чтения базы данных.
Набор результатов может содержать строки, которые еще не были зафиксированы, которые позже часто откатываются.
Если WITH (NOLOCK) применяется к таблице с некластеризованным индексом, то индексы строк могут быть изменены другими транзакциями, поскольку данные строки передаются в таблицу результатов. Это означает, что в наборе результатов могут отсутствовать строки или одна и та же строка может отображаться несколько раз.
READ COMMITTED добавляет дополнительную проблему, когда данные повреждены в одном столбце, когда несколько пользователей изменяют одну и ту же ячейку одновременно.
Эти ответы ТАК и DBA немного яснее относительно того, что на самом деле происходит.