Является ли nolock (подсказка Sql Server) плохой практикой?

Я занимаюсь созданием веб-сайта и приложений, которые не критически важная миссия - > например. банковского программного обеспечения, космических полетов, интенсивной терапии, мониторинга приложений и т. д. Вы поняли идею.

Итак, с этим массовым отказом от ответственности, плохо ли использовать подсказку NOLOCK в какой-то инструкции Sql? Несколько лет назад один из администраторов Sql предложил мне использовать NOLOCK, если я доволен "грязным чтением" , которое даст мне немного больше производительности моя система, потому что каждое чтение не блокирует таблицу/строку/что угодно.

Мне также сказали, что это отличное решение, если я испытываю тупиков. Итак, я начал следовать этой мысли в течение нескольких лет, пока гуру Sql не помог мне с некоторым случайным кодом и не заметил все NOLOCKS в моем коде sql. Меня вежливо отругали, и он попытался объяснить мне (почему это нехорошо), и я вроде как заблудился. Я чувствовал, что суть его объяснения была "это пластырь решение более серьезная проблема. . особенно, если вы испытываете тупик. Таким образом, исправьте корень проблемы".

недавно я немного погуглил об этом и наткнулся этот пост.

Итак, может ли какой-нибудь гуру sql db sensei просветить меня?

12 ответов


с подсказкой NOLOCK, уровень изоляции транзакции для SELECT заявление READ UNCOMMITTED. Это означает, что запрос может видеть грязные и несогласованные данные.

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

Я предлагаю чтение Для Снимок Изоляция помогает и когда больно - MSDN рекомендует использовать Read COMMITTED SNAPSHOT, а не SNAPSHOT в большинстве случаев.


до работы над переполнением стека я был против NOLOCK на принципале, который вы потенциально можете выполнить SELECT С NOLOCK и вернуть результаты с данными, которые могут быть устаревшими или противоречивы. Следует подумать о том, сколько записей может быть вставлено/Обновлено в то же время, когда другой процесс может выбирать данные из той же таблицы. Если это происходит много, то существует высокая вероятность тупиков, если вы не используете режим базы данных, такой как READ COMMITED SNAPSHOT.

С тех пор я изменил свою точку зрения на использование NOLOCK увидев, как он может улучшить SELECT производительность, а также устранение блокировок на массово загруженном SQL Server. Иногда вам может быть все равно, что ваши данные не на 100% зафиксированы, и вам нужны результаты быстро, даже если они могут быть устаревшими.

задайте себе вопрос, когда думаете об использовании NOLOCK:

мой запрос включает таблицу с большим числом INSERT/UPDATE команды и мне все равно, если данные, возвращенные из запроса, могут отсутствовать эти изменения в данный момент?

если ответ нет, то используйте NOLOCK для повышения производительности.


Я только что выполнил быстрый поиск NOLOCK ключевое слово в базе кода для переполнения стека и найдено 138 экземпляров, поэтому мы используем его в нескольких местах.

Если вы не заботитесь о грязных чтениях (т. е. в преимущественно читаемой ситуации), то NOLOCK - Это хорошо.

но, имейте в виду, что большинство проблем с блокировкой связано с отсутствием "правильных" индексов для рабочей нагрузки запроса (при условии, что оборудование соответствует задаче).

редактировать: Я определенно не предполагаю, что NOLOCK должно быть использовано. Думаю, я должен был ясно дать это понять. (Я бы использовал его только в экстремальных обстоятельствах, когда я проанализировал, что все в порядке). Например, некоторое время назад я работал над некоторыми TSQL, которые были посыпаны NOLOCK, чтобы попытаться облегчить проблемы блокировки. Я удалил их все, реализовал правильные индексы, и все тупики ушли.


сомневаюсь, что это был" гуру", у которого был какой-либо опыт в высоком трафике...

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

тем не менее, если у вас есть несколько слоев, построенных на вашем выборе, вы можете строить в опасной избыточности. Если вы имеете дело сценарии денег или статуса, тогда вам нужно не только чтение/запись транзакционных данных, но и правильное решение параллелизма (то, что большинство "гуру" не беспокоятся).

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

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

EDIT: это не просто тупики, с которыми это помогает, это также то, сколько вы собираетесь заставить всех ждать, пока вы закончите, или наоборот.

используя подсказку NOLOCK в EF4?


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

  • при запросе одиночных значений / строк это всегда плохая практика использования NOLOCK -- вы, вероятно, никогда не хотите отображать неправильную информацию или, возможно, даже предпринимать какие-либо действия по неправильным данным.
  • показывая грубую статистическую информацию, НОЛОК может быть очень полезно. Так в качестве примера: было бы глупо брать замки читать точно количество просмотров вопрос или точное количество вопросов для тега. Никого не волнует, если вы неправильно сформулируете 3360 вопросов с тегом "sql-server" сейчас, и из-за отката транзакции 3359 вопросов через секунду.

Как профессиональный разработчик я бы сказал, Это зависит. Но я определенно следую советам GATS и OMG Ponies. Знайте, что вы делаете, знаете, когда это помогает и когда это больно и

читать подсказки и другие плохие идеи

Что может заставить вас понять sql server глубже. Обычно я следую правилу, что подсказки SQL-это зло, но, к сожалению, я использую их время от времени, когда мне надоедает заставлять SQL server делать что-то... Но это редко случаи.

люк


когда app-support хотел ответить на запросы ad-hock от производственного сервера с использованием SSMS (которые не обслуживались через отчетность), я попросил их использовать nolock. Таким образом, "основной" бизнес не пострадает.


Я согласен с некоторыми комментариями о подсказке NOLOCK и особенно с теми, кто говорит:"используйте его, когда это уместно". Если приложение написано плохо и использует параллелизм неуместным способом – это может вызвать эскалацию блокировки. Высоко транзакционная таблица также блокируется все время из-за их природы. Наличие хорошего покрытия индекса не поможет получить данные, но установка уровня изоляции для чтения незафиксированных делает. Также я считаю, что использование подсказки NOLOCK безопасно во многих случаях когда характер изменений предсказуем. Например-в производстве, когда задания с путешественниками проходят различные процессы с большим количеством вставок измерений, вы можете безопасно выполнить запрос к готовому заданию с подсказкой NOLOCK и таким образом избежать столкновения с другими сеансами, которые ставят повышенные или эксклюзивные блокировки на таблицу/страницу. Данные, к которым вы обращаетесь в этом случае, статичны, но они могут находиться в очень транзакционной таблице с сотнями миллионов записей и тысячами обновления/вставки в минуту. Ура!--1-->


Я считаю, что практически никогда не правильно использовать nolock.

Если Вы читаете одну строку, то правильный индекс означает, что вам не понадобится NOLOCK, поскольку отдельные действия строки завершаются быстро.

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

NOLOCK-это суррогатный тег для "Мне все равно, если это ответ содержит повторяющиеся строки, строки, которые удаляются, или строки, которые никогда не вставлялись из-за отката"

ошибки, которые возможны при NOLOCK:

  • строк, которые соответствуют не возвращаются вообще.
  • одиночные строки возвращаются несколько раз (включая несколько экземпляров одного и того же первичного ключа)
  • возвращаются строки, которые не совпадают.

любое действие, которое может вызвать разделение страницы во время nolock select работает может вызвать эти вещи. Почти любое действие (даже удаление) может вызвать разделение страницы.

поэтому: если вы" знаете", что строка не будет изменена во время работы, не используйте nolock, так как индекс позволит эффективно извлекать.

Если вы подозреваете, что строка может измениться во время выполнения запроса, и вы заботитесь о точности, не используйте nolock.

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


лучшие решения, когда это возможно:

  • Реплицируйте данные (с помощью репликации журнала) в базу данных отчетов.
  • используйте снимки SAN и смонтируйте согласованную версию DB
  • используйте базу данных, которая имеет лучший фундаментальный уровень изоляции транзакций

уровень изоляции транзакции моментального снимка был создан, потому что MS теряла продажи Oracle. Oracle использует журналы отмены/повтора, чтобы избежать этой проблемы. Postgres использует MVCC. В названием heckaton будущем МС использует MVCC, но это лет от производства готов.


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

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

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

Это потому, что другие транзакции перемещают данные одновременно с их чтением.

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


в реальной жизни, где вы столкнетесь систем уже написано и добавление индексов к таблицам, затем резко тормозит загрузка данных из 14gig данные таблицы, вы иногда вынуждены использовать с nolock на ваши отчеты и в конце месяца proessing так, что совокупность функций (сумма, количество и т. д.) Не строки, страницы, таблицы замок и deteriate общую производительность. Легко сказать в новой системе никогда не используйте с nolock и используйте индексы - но добавление индексов severly понижает загрузку данных и когда мне говорят, Ну, измените базу кода для удаления индексов, затем массовая загрузка, а затем воссоздайте индексы - что все хорошо, если вы разрабатываете новую систему. Но не тогда, когда у вас уже есть система.