Является ли неправильная практика NOLOCK (Sql Server hint)?

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

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

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

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

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

Ответ 1

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

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

Я предлагаю читать Когда функция выделения снимков помогает и когда она борется - MSDN рекомендует в большинстве случаев использовать READ COMMITTED SNAPSHOT, а не SNAPSHOT.

Ответ 2

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

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

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

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

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


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

Ответ 3

Если вы не заботитесь о грязных чтениях (то есть в ситуации READ), тогда NOLOCK отлично.

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

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

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

Ответ 4

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

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

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

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

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

РЕДАКТИРОВАТЬ: Это не просто взаимоблокировки, с которыми это помогает, это также то, как вы собираетесь заставить всех ждать, пока вы не закончите, или наоборот.

Использование подсказки NOLOCK в EF4?

Ответ 5

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

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

Ответ 6

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

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

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

Лука

Ответ 7

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

Ответ 8

Я согласен с некоторыми комментариями о подсказке NOLOCK и особенно с теми, кто говорит "используйте его, когда он подходит". Если приложение плохо написано и использует concurrency неприемлемый путь - это может вызвать эскалацию блокировки. Высокая транзакционная таблица также постоянно блокируется из-за их характера. Хороший охват индексами не поможет с извлечением данных, но установка уровня ISOLATION LEAD READ UNCOMMITTED делает. Также я считаю, что использование подсказки NOLOCK безопасно во многих случаях, когда характер изменений предсказуем. Например, при производстве, когда рабочие места с путешественниками проходят через различные процессы с большим количеством вставок измерений, вы можете безопасно выполнять запрос к завершенному заданию с помощью подсказки NOLOCK и таким образом избегать столкновения с другими сеансами, которые помещают блокировки PROMOTED или EXCLUSIVE в таблицу/стр. Данные, к которым вы обращаетесь в этом случае, являются статическими, но могут находиться в очень транзакционной таблице с сотнями миллионов записей и тысяч обновлений/вставок в минуту. Приветствия

Ответ 9

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

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

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

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

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

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

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

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

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

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

Ответ 10

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

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

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

Ответ 11

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

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

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

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

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

Ответ 12

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