Что такое использование & amp; преимущество использования с (nolock) [duplicate]

Убедитесь, что кодировка символов и сопоставление для двух таблиц одинаковы.

В моем случае одна из таблиц использовала utf8, а другая - latin1.

У меня был другой случай, когда кодировка была одинаковой, но сортировка различна. Один utf8_general_ci другой utf8_unicode_ci

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

ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Надеюсь, это поможет кому-то.

526
задан TylerH 14 March 2018 в 05:52
поделиться

16 ответов

WITH (NOLOCK) является эквивалентом использования READ UNCOMMITED в качестве уровня изоляции транзакции. Таким образом, вы рискуете прочитать незафиксированную строку, которая впоследствии будет откат, т. Е. Данные, которые никогда не попадали в базу данных. Таким образом, хотя это может помешать чтению заходить в тупик другими операциями, это сопряжено с риском. В банковском приложении с высокими ставками транзакций это, вероятно, не будет правильным решением любой проблемы, которую вы пытаетесь решить с помощью IMHO.

384
ответ дан David M 17 August 2018 в 10:27
поделиться
  • 1
    Большинство банковских приложений могут безопасно использовать nolock, поскольку они являются транзакционными в бизнес-смысле. Вы только пишете новые строки, вы никогда не обновляете их. – Jonathan Allen 26 March 2009 в 18:56
  • 2
    @ Grauenwolf - вставленный, но незафиксированный ряд может по-прежнему приводить к грязным чтениям. – saasman 26 March 2009 в 22:03
  • 3
    @ Saasman- Если вы никогда не отказываетесь от транзакций, это не имеет значения. И с таблицей только для вставки шансы на откат незначительны. И если они произойдут, вы все равно исправите все это в отчете о дисперсии в конце дня. – Jonathan Allen 27 March 2009 в 19:47
  • 4
    Если вы используете NOLOCK с SELECT, вы рискуете возвращать одни и те же строки более одного раза (дублированные данные), если данные когда-либо вставлены (или обновлены) в таблицу при выполнении выбора. – Ian Boyd 19 September 2013 в 01:31
  • 5
    @JonathanAllen Это просто совершенно неправильно. Когда записывается новая строка и разрезается страница, данные могут перемещаться между страницами. Это может привести к возврату повторяющихся строк, а некоторые строки могут быть пропущены. Пожалуйста, НЕ ВСЕГДА используйте nolock в банковском приложении. – Sean Lange 25 July 2014 в 19:31

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

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

8
ответ дан Andrew Hare 17 August 2018 в 10:27
поделиться
  • 1
    Удивительно, но при работе с финансовыми данными это не проблема. Поскольку строки никогда не редактируются, а учетные записи сверяются в конце дня, чтение временно поддельных данных ничего не делает. – Jonathan Allen 26 March 2009 в 19:00

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

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

Это особенно полезно, если у вас есть отчеты типа OLAP, которые вы используете против базы данных OLTP.

Первый вопрос, который нужно задать, хотя , «почему я беспокоюсь об этом?» По моему опыту, мошенничество по умолчанию блокировки часто происходит, когда кто-то находится в режиме «попробуй что-нибудь», и это один случай, когда неожиданные последствия маловероятны. Слишком часто это случай преждевременной оптимизации и может быть слишком легко вставлен в приложение «на всякий случай». Важно понять, почему вы это делаете, какую проблему он решает, и есть ли у вас проблема.

13
ответ дан dkretz 17 August 2018 в 10:27
поделиться

Самый простой ответ - простой вопрос - нужны ли вам результаты, которые можно было бы повторить? Если да, то NOLOCKS не подходит ни при каких обстоятельствах.

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

3
ответ дан Ed Green 17 August 2018 в 10:27
поделиться

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

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

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

15
ответ дан Joel Coehoorn 17 August 2018 в 10:27
поделиться
  • 1
    Как человек, который работает над банковскими приложениями, я должен сказать, что блокировки не являются проблемой. Транзакционные записи, то есть строки, которые вставлены, но никогда не обновляются или не удаляются, удивительно устойчивы к проблемам чтения неквалифицированных данных. – Jonathan Allen 26 March 2009 в 19:02

Короткий ответ:

Никогда не используйте WITH (NOLOCK).

Длинный ответ:

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

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

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

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

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

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

Можно утверждать, что использовать его в местах, где вы можете с ним справиться, хорошо, но в чем смысл? Я не могу придумать какую-либо ситуацию, когда допустимы поврежденные данные.

Никогда не используйте NOLOCK когда-либо.

(когда-либо)

4
ответ дан Knickerless-Noggins 17 August 2018 в 10:27
поделиться
  • 1
    Чтение незафиксированных данных приемлемо, если оно не изменяет окончательное решение. Например, если вы пытаетесь спрогнозировать, сколько денег ваш розничный магазин будет делать в течение следующих 6 месяцев, то, увидев, что Тэмми купила 2 рулона бумажных полотенец, когда она действительно купила 3, не изменит ваше мнение о будущем , – Jonathan Allen 2 August 2016 в 09:57
  • 2
    Если теперь ваш фильтр включен, ваши данные будут неточными в момент запуска запроса. Если ваш фильтр содержит только исторические данные, использование READ UNCOMITTED вообще не повлияет на него. Существует причина, почему он был включен в стандарт ANSI. – Jonathan Allen 2 August 2016 в 23:18
  • 3
    Никогда не говори никогда. Если вам нужно, чтобы данные были на 100% точными, вам не следует использовать nolock. Для меня это обычно не так. При представлении данных пользователю, к тому времени, когда они действуют на данные, он, возможно, уже изменился в любом случае, но, скорее всего, этого не произошло, и конфликт блокировок не стоит задержек ответа. – Perposterer 26 February 2018 в 16:44
  • 4
    WITH (NOLOCK) - это взлом, и он не только возвращает неправильные значения, но также возвращает ошибочные данные. Во что бы то ни стало, используйте это, если вы в порядке с этими проблемами, но в таком случае вам лучше подумать, что вам также не нужна база данных. Вас обманули – Knickerless-Noggins 23 March 2018 в 15:27

Используйте nolock, когда вы в порядке с «грязными» данными. Это означает, что nolock также может считывать данные, которые находятся в процессе изменения и / или незафиксированных данных.

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

6
ответ дан Learning 17 August 2018 в 10:27
поделиться
  • 1
    Единственный раз, когда вам это нужно, - это высокая транзакционная среда. Если ваши таблицы в основном неактивны, тогда вы ничего не получите. – Jonathan Allen 26 March 2009 в 19:13

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

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

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

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

Справедливости ради, вот два специальных сценария, в которых подсказка nolock может предоставить полезность

1) База данных SQL Server до 2005 года, которая должна запускать длительный запрос в отношении текущей базы данных OLTP, это может быть единственный способ

2) Плохо написанное приложение, которое блокирует записи и возвращает управление пользовательскому интерфейсу и считывающим устройствам, блокируется неограниченно. Nolock может быть полезен здесь, если приложение не может быть исправлено (сторонний и т. Д.), А база данных либо до 2005 года, либо управление версиями не может быть включено.

30
ответ дан meagar 17 August 2018 в 10:27
поделиться
  • 1
    Я согласен с вами в том, что NOLOCK нельзя использовать, чтобы компенсировать плохо написанный код. Тем не менее, я думаю, что ваша атака Джонатана необоснованна, поскольку он никогда не упоминал транзакции database . Он просто указывал, что финансовые приложения обычно не позволяют редактировать записи (очевидно, есть некоторые исключения). В примере с перечислением средств он говорит, что было бы странно, если бы вы были mutate значение баланса учетной записи вместо добавления записи дебетования / кредита в регистр учета , – chrnola 22 April 2014 в 16:06
  • 2
    Когда средства перечисляются с одного счета на другой в разных банках, как вы думаете, что происходит? В некоторой uber-базе данных есть блокировка на столе в Bank of America, а другая в Wells Fargo? Нет. Финансовая транзакция записывается в каждый из них, а затем в конце концов, что все записи совпадают. – Jonathan Allen 25 July 2014 в 19:58

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

7
ответ дан Otávio Décio 17 August 2018 в 10:27
поделиться
  • 1
    Мы делаем что-то подобное, чтобы представить фоновую задачу с очередью работы. Если, когда он попадает в определенную запись, он больше не существует / не соответствует критериям выбора, он просто переходит к следующему. – TripeHound 25 April 2014 в 09:26

Вопрос в том, что хуже:

  • тупик или
  • неправильное значение?

Для финансовых баз данных, тупики намного хуже неправильных значений. Я знаю, что это звучит в обратном направлении, но выслушайте меня. Традиционным примером транзакций БД является обновление двух строк, вычитание из одного и добавление в другое. Это неправильно.

В финансовой базе данных вы используете деловые операции. Это означает добавление одной строки в каждую учетную запись. Крайне важно, чтобы эти транзакции завершились, и строки были успешно записаны.

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

При этом SQL Server 2005 исправил большинство ошибок, которые сделали NOLOCK необходимо. Поэтому, если вы не используете SQL Server 2000 или более раннюю версию, вам это не понадобится.

Дальнейшее чтение Версии уровня строк

152
ответ дан Robert Harvey 17 August 2018 в 10:27
поделиться
  • 1
    Неправильное получение баланса счета временно не является большим делом? Что делать, если эта транзакция является той, в которой вы берете наличные деньги из атма без лимита овердрафта? – Learning 26 March 2009 в 19:15
  • 2
    @Learning: Что произойдет, если вы выберете деньги за 30 секунд до того, как кто-то зарядит вашу карту? До тех пор, пока всякое общение не станет частым, овердрафты станут фактом жизни. – Jonathan Allen 27 March 2009 в 19:44
  • 3
    +1 В финансовом приложении (везде, не только в банках) нет ни обновлений, ни удалений. Даже неправильные операции корректируются путем вставки записей. Что это за термин на английском? Является ли это «storno»? Google не помог мне ответить на этот вопрос – Gennady Vanin Геннадий Ванин 1 October 2010 в 02:23
  • 4
    Поздний вход ... тупики должны быть пойманы и повторены. Грязные чтения имеют последствия – gbn 29 September 2011 в 20:20
  • 5
    @JonathanAllen просто fyi, термин UTmost, а не UP. – Escobar Ceaser 20 August 2013 в 19:10

Пример текстовой книги для законного использования подсказки nolock - это выборка отчета в базе данных OLTP с высоким уровнем обновления.

Чтобы принять актуальный пример. Если бы крупный банк США на высоких улицах захотел запустить почасовой отчет о поиске первых признаков городского уровня, которые выполнялись в банке, запрос на нолоке мог бы сканировать транзакционные таблицы, суммирующие денежные депозиты и снятие наличных денег в каждом городе. Для такого отчета крошечный процент ошибок, вызванных транзакциями с откатным обновлением, не снизит значение отчета.

48
ответ дан saasman 17 August 2018 в 10:27
поделиться

NOLOCK эквивалентно READ UNCOMMITTED, однако Microsoft заявляет, что вы не должны использовать его для операторов UPDATE или DELETE:

Для операторов UPDATE или DELETE: эта функция будет быть удалены в будущей версии Microsoft SQL Server. Избегайте использования этой функции в новых разработках и планируйте изменять приложения, которые в настоящее время используют эту функцию.

http://msdn.microsoft.com/en-us/library/ ms187373.aspx

Эта статья относится к SQL Server 2005, поэтому поддержка NOLOCK существует, если вы используете эту версию. В целях обеспечения будущего кода (при условии, что вы решили использовать грязные чтения) вы можете использовать это в своих хранимых процедурах:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

23
ответ дан Seibar 17 August 2018 в 10:27
поделиться

Мои 2 цента - имеет смысл использовать WITH (NOLOCK), когда вам нужно создавать отчеты. На этом этапе данные не будут сильно меняться. вы не захотите блокировать эти записи.

9
ответ дан SoftwareGeek 17 August 2018 в 10:27
поделиться
  • 1
    Я думаю, что WITH (NoLOCK) лучше, если вас не волнуют текущие изменения. – Abdul Saboor 11 March 2013 в 18:06

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

Проверьте статью Ицика Бен-Гана . Вот выдержка:

"С подсказкой NOLOCK (или установкой уровня изоляции сеанса на READ UNCOMMITTED) вы указываете SQL Server, что вы не ожидаете согласованности, поэтому никаких гарантий нет. Имейте в виду, что «несогласованные данные» означают не только то, что вы можете увидеть незафиксированные изменения, которые были впоследствии отменены, или изменения данных в промежуточном состоянии транзакции. Это также означает, что в простом запросе, который сканирует всю таблицу / индекс данные SQL Server могут потерять позицию сканирования, или вы можете получить одну и ту же строку дважды. "

47
ответ дан Toby J 17 August 2018 в 10:27
поделиться
  • 1
    Немного ниже он объясняет, как получить одну и ту же строку дважды: Я воссоздаю таблицу T1, чтобы кластеризованный индекс в col1 был определен как уникальный индекс с опцией IGNORE_DUP_KEY. Это означает, что дублирующиеся значения не могут существовать в col1, а также что попытка вставить дубликат ключа не приведет к сбою транзакции и генерирует ошибку, а просто генерирует предупреждение. Если вы не используете эту странную опцию, вы, вероятно, не нужно беспокоиться о том, чтобы получить строки дважды – JanHudecek 10 March 2012 в 15:00
  • 2
    Вы все равно можете получать строки с ошибками даже без проводной опции - если ваш запрос использует индекс, который не является уникальным, например. Тем не менее это не уникально для нолока. – RMD 8 November 2013 в 07:10

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

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

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

16
ответ дан TylerH 17 August 2018 в 10:27
поделиться
  • 1
    было бы неплохо, если бы вы упоминали о том, что SQL Server 2005 имеет управление версиями строк, поэтому nolocks больше не нужны. – Jonathan Allen 26 March 2009 в 19:09
  • 2
    Ну, & quot; с (nolock) & quot; все еще имеет место даже в SQL Server 2005, но преимущества становятся все более стройными и стройными, это правда. – marc_s 26 March 2009 в 21:38

Я использую подсказку (nolock), особенно в базах данных SQLServer 2000 с высокой активностью. Я не уверен, что это необходимо в SQL Server 2005. Недавно я добавил этот намек на SQL Server 2000 по просьбе клиента DBA, потому что он замечал множество блокировок записей SPID.

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

Кстати, базы данных, с которыми я имею дело, являются справочными системами корпоративных медицинских заявок, поэтому мы говорим о миллионах записей и 20 + таблицы во многих объединениях. Обычно я добавляю подсказку WITH (nolock) для каждой таблицы в объединении (если только это не производная таблица, и в этом случае вы не можете использовать этот конкретный намек)

6
ответ дан user52212 17 August 2018 в 10:27
поделиться
  • 1
    SQL Server 2005 добавлен «управление версиями строк», что должно значительно снизить потребность в nolocks. Недавно мы обновили и не тренируем наших администраторов баз данных, чтобы прекратить их использовать. – Jonathan Allen 26 March 2009 в 19:11
Другие вопросы по тегам:

Похожие вопросы: