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



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



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



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



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



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

562   12  

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 - Это хорошо.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

люк

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Comments

    Ничего не найдено.