Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

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

Я предлагаю прочитать Когда Изоляция моментального снимка Помогает, а когда вредит - в большинстве случаев MSDN рекомендует использовать МОМЕНТАЛЬНЫЙ СНИМОК с ФИКСАЦИЕЙ ЧТЕНИЯ, а не МОМЕНТАЛЬНЫЙ СНИМОК.

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

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

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

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

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

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


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

Если вас не волнуют грязные чтения (т.е.в ситуации преимущественного ЧТЕНИЯ), затем NOLOCK все в порядке.

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

И объяснение гуру было правильным.Обычно это пластыревое решение более серьезной проблемы.

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

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

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

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

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

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

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

Используете подсказку NOLOCK в EF4?

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

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

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

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

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

люк

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

Я согласен с некоторыми комментариями по поводу подсказки NOLOCK и особенно с теми, которые говорят "используйте ее, когда это уместно".Если приложение написано плохо и использует параллелизм ненадлежащим образом – это может привести к эскалации блокировки.Таблицы с высокой степенью транзакционности также постоянно блокируются из-за своей природы.Хорошее покрытие индексом не поможет с извлечением данных, но установка УРОВНЯ ИЗОЛЯЦИИ для ЧТЕНИЯ БЕЗ ОГРАНИЧЕНИЙ поможет.Также я считаю, что использование подсказки NOLOCK безопасно во многих случаях, когда характер изменений предсказуем.Например, на производстве, когда задания с путешественниками проходят различные процессы с большим количеством вставок измерений, вы можете безопасно выполнить запрос к готовому заданию с помощью подсказки NOLOCK и таким образом избежать столкновения с другими сеансами, которые устанавливают ПОВЫШЕННЫЕ или ЭКСКЛЮЗИВНЫЕ блокировки для таблицы / страницы.Данные, к которым вы обращаетесь в этом случае, статичны, но они могут находиться в таблице транзакций с сотнями миллионов записей и тысячами обновлений / вставок в минуту.Ваше здоровье

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

Если вы читаете одну строку, то правильный индекс означает, что вам не понадобится БЛОКИРОВКА, поскольку действия с отдельными строками выполняются быстро.

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

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

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

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

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

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

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

Если вы рассматриваете возможность блокировки из-за взаимоблокировок, изучите структуру плана запроса на предмет непредвиденных проверок таблицы, проследите взаимоблокировки и выясните, почему они возникают.ОТСУТСТВИЕ блокировки при записи может означать, что запросы, которые ранее зашли в тупик, потенциально оба будут выдавать неправильный ответ.

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

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

Уровень изоляции транзакций МОМЕНТАЛЬНОГО снимка был создан из-за того, что MS теряла продажи Oracle.Oracle использует журналы отмены / повтора, чтобы избежать этой проблемы.Postgres использует MVCC.В будущем MS's Heckaton будет использовать MVCC, но до готовности к производству еще много лет.

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

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

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

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

ЗАФИКСИРОВАННОЕ ЧТЕНИЕ добавляет дополнительную проблему, связанную с повреждением данных в пределах одного столбца, когда несколько пользователей одновременно изменяют одну и ту же ячейку.

В реальной жизни, когда вы сталкиваетесь с уже написанными системами, и добавление индексов к таблицам затем резко замедляет загрузку данных из 14-гигабайтной таблицы данных, вы иногда вынуждены использовать NOLOCK в своих отчетах и обработке на конец месяца, чтобы совокупные функции (sum, count и т.д.) Не блокировали строку, страницу, таблицу и ухудшали общую производительность.Легко сказать, что в новой системе никогда не используйте WITH NOLOCK и используйте индексы - но добавление индексов серьезно снижает загрузку данных, и когда мне затем говорят, что хорошо, измените базу кода, чтобы удалить индексы, затем массово загружайте, а затем воссоздавайте индексы - что все хорошо, если вы разрабатываете новую систему.Но не тогда, когда у вас уже есть система.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top