Убедитесь, что кодировка символов и сопоставление для двух таблиц одинаковы.
В моем случае одна из таблиц использовала utf8
, а другая - latin1
.
У меня был другой случай, когда кодировка была одинаковой, но сортировка различна. Один utf8_general_ci
другой utf8_unicode_ci
Вы можете запустить эту команду, чтобы установить кодировку и сопоставление для таблицы.
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Надеюсь, это поможет кому-то.
WITH (NOLOCK) является эквивалентом использования READ UNCOMMITED в качестве уровня изоляции транзакции. Таким образом, вы рискуете прочитать незафиксированную строку, которая впоследствии будет откат, т. Е. Данные, которые никогда не попадали в базу данных. Таким образом, хотя это может помешать чтению заходить в тупик другими операциями, это сопряжено с риском. В банковском приложении с высокими ставками транзакций это, вероятно, не будет правильным решением любой проблемы, которую вы пытаетесь решить с помощью IMHO.
Если вы занимаетесь финансовыми транзакциями, вы никогда не захотите использовать nolock
. nolock
лучше всего выбирать из больших таблиц с множеством обновлений, и вам все равно, если запись, которую вы получаете, может быть устаревшей.
Для финансовых записей (и почти всех других записей в большинство приложений) nolock
может привести к хаосу, поскольку вы могли бы читать данные из записи, которая была записана, и не получать правильные данные.
Простой ответ - всякий раз, когда ваш SQL не изменяет данные, и у вас есть запрос, который может мешать другим действиям (через блокировку).
Стоит рассмотреть любые запросы, используемые для отчетов, особенно если запрос занимает больше, чем, скажем, 1 секунду.
Это особенно полезно, если у вас есть отчеты типа OLAP, которые вы используете против базы данных OLTP.
Первый вопрос, который нужно задать, хотя , «почему я беспокоюсь об этом?» По моему опыту, мошенничество по умолчанию блокировки часто происходит, когда кто-то находится в режиме «попробуй что-нибудь», и это один случай, когда неожиданные последствия маловероятны. Слишком часто это случай преждевременной оптимизации и может быть слишком легко вставлен в приложение «на всякий случай». Важно понять, почему вы это делаете, какую проблему он решает, и есть ли у вас проблема.
Самый простой ответ - простой вопрос - нужны ли вам результаты, которые можно было бы повторить? Если да, то NOLOCKS не подходит ни при каких обстоятельствах.
Если вам не нужна повторяемость, то nolocks могут быть полезны, особенно если вы не контролируете все процессы, подключающиеся к целевой базе данных.
Другой случай, когда это обычно нормально, находится в базе данных отчетов, где данные, возможно, уже поставлены и записи просто не происходят. В этом случае параметр должен быть установлен на уровне базы данных или таблицы администратором, изменив уровень изоляции по умолчанию.
В общем случае: вы можете использовать его, когда вы очень уверен, что читать старые данные можно. Важно помнить, что его очень легко получить это неправильно . Например, даже если в момент написания запроса все нормально, уверены ли вы, что в будущем в базе данных не будет изменений, чтобы сделать эти обновления более важными?
Я также сделаю предположение, что это, вероятно, не хорошая идея в банковском приложении. Или приложение инвентаризации. Или где бы вы ни думали о транзакциях.
Короткий ответ:
Никогда не используйте WITH (NOLOCK)
.
Длинный ответ:
NOLOCK часто используется как волшебный способ ускорить чтение базы данных, но я стараюсь избегать его использования там, где это возможно.
Результирующий набор может содержать строки, которые еще не были зафиксированы, которые часто позже откатываются.
Ошибка или результат может быть пустым, пропускать строки или отображать одну и ту же строку несколько раз.
Это связано с тем, что другие транзакции перемещают данные одновременно с чтением.
READ COMMITTED добавляет дополнительная проблема, когда данные повреждаются в одном столбце, где несколько пользователей одновременно меняют одну и ту же ячейку.
Есть и другие побочные эффекты, которые приводят к жертве увеличения скорости, которое вы надеялись получить в первом место.
Можно утверждать, что использовать его в местах, где вы можете с ним справиться, хорошо, но в чем смысл? Я не могу придумать какую-либо ситуацию, когда допустимы поврежденные данные.
Никогда не используйте NOLOCK когда-либо.
(когда-либо)
READ UNCOMITTED
вообще не повлияет на него. Существует причина, почему он был включен в стандарт ANSI.
– Jonathan Allen
2 August 2016 в 23:18
WITH (NOLOCK)
- это взлом, и он не только возвращает неправильные значения, но также возвращает ошибочные данные. Во что бы то ни стало, используйте это, если вы в порядке с этими проблемами, но в таком случае вам лучше подумать, что вам также не нужна база данных. Вас обманули
– Knickerless-Noggins
23 March 2018 в 15:27
Используйте nolock, когда вы в порядке с «грязными» данными. Это означает, что nolock также может считывать данные, которые находятся в процессе изменения и / или незафиксированных данных.
Обычно не рекомендуется использовать его в среде с высокой транзакцией, поэтому он не является параметром по умолчанию для запроса.
Не знаете, почему вы не обертываете финансовые транзакции в транзакциях с базой данных (например, когда вы переводите средства с одной учетной записи на другую - вы не совершаете одну сторону транзакции одновременно - вот почему существуют явные транзакции) , Даже если ваш код работает с бизнес-транзакциями, поскольку это похоже на то, что все транзакционные базы данных могут делать неявные откаты в случае ошибок или сбоев. Я думаю, что это обсуждение на вашей голове.
Если у вас проблемы с блокировкой, выполните управление версиями и очистите свой код.
Никакая блокировка не только возвращает неправильные значения, она возвращает фантомные записи и дубликаты.
Это распространенное заблуждение, что он всегда заставляет запросы работать быстрее. Если в таблице нет блокировок записи, это не имеет никакого значения. Если на столе есть блокировки, это может сделать запрос быстрее, но есть причина, по которой в первую очередь были созданы блокировки.
Справедливости ради, вот два специальных сценария, в которых подсказка nolock может предоставить полезность
1) База данных SQL Server до 2005 года, которая должна запускать длительный запрос в отношении текущей базы данных OLTP, это может быть единственный способ
2) Плохо написанное приложение, которое блокирует записи и возвращает управление пользовательскому интерфейсу и считывающим устройствам, блокируется неограниченно. Nolock может быть полезен здесь, если приложение не может быть исправлено (сторонний и т. Д.), А база данных либо до 2005 года, либо управление версиями не может быть включено.
Я использовал для получения «следующей партии» для вещей. В этом случае не имеет значения точный элемент, и у меня есть много пользователей, которые запускают этот же запрос.
Вопрос в том, что хуже:
Для финансовых баз данных, тупики намного хуже неправильных значений. Я знаю, что это звучит в обратном направлении, но выслушайте меня. Традиционным примером транзакций БД является обновление двух строк, вычитание из одного и добавление в другое. Это неправильно.
В финансовой базе данных вы используете деловые операции. Это означает добавление одной строки в каждую учетную запись. Крайне важно, чтобы эти транзакции завершились, и строки были успешно записаны.
Неправильное получение баланса аккаунта неправильно, это то, к чему подходит согласование на конец дня. И овердрафт с учетной записи гораздо более вероятен, потому что два банкомата используются одновременно, а не из-за незафиксированного чтения из базы данных.
При этом SQL Server 2005 исправил большинство ошибок, которые сделали NOLOCK
необходимо. Поэтому, если вы не используете SQL Server 2000 или более раннюю версию, вам это не понадобится.
Дальнейшее чтение Версии уровня строк
Пример текстовой книги для законного использования подсказки nolock - это выборка отчета в базе данных OLTP с высоким уровнем обновления.
Чтобы принять актуальный пример. Если бы крупный банк США на высоких улицах захотел запустить почасовой отчет о поиске первых признаков городского уровня, которые выполнялись в банке, запрос на нолоке мог бы сканировать транзакционные таблицы, суммирующие денежные депозиты и снятие наличных денег в каждом городе. Для такого отчета крошечный процент ошибок, вызванных транзакциями с откатным обновлением, не снизит значение отчета.
NOLOCK
эквивалентно READ UNCOMMITTED
, однако Microsoft заявляет, что вы не должны использовать его для операторов UPDATE
или DELETE
:
Для операторов UPDATE или DELETE: эта функция будет быть удалены в будущей версии Microsoft SQL Server. Избегайте использования этой функции в новых разработках и планируйте изменять приложения, которые в настоящее время используют эту функцию.
blockquote>http://msdn.microsoft.com/en-us/library/ ms187373.aspx
Эта статья относится к SQL Server 2005, поэтому поддержка
NOLOCK
существует, если вы используете эту версию. В целях обеспечения будущего кода (при условии, что вы решили использовать грязные чтения) вы можете использовать это в своих хранимых процедурах:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
Мои 2 цента - имеет смысл использовать WITH (NOLOCK
), когда вам нужно создавать отчеты. На этом этапе данные не будут сильно меняться. вы не захотите блокировать эти записи.
К сожалению, это не просто чтение нефиксированных данных. В фоновом режиме вы можете в два раза увеличить число страниц (в случае разделения страниц), или вы можете вообще пропустить страницы. Таким образом, ваши результаты могут быть сильно искажены.
Проверьте статью Ицика Бен-Гана . Вот выдержка:
"С подсказкой NOLOCK (или установкой уровня изоляции сеанса на READ UNCOMMITTED) вы указываете SQL Server, что вы не ожидаете согласованности, поэтому никаких гарантий нет. Имейте в виду, что «несогласованные данные» означают не только то, что вы можете увидеть незафиксированные изменения, которые были впоследствии отменены, или изменения данных в промежуточном состоянии транзакции. Это также означает, что в простом запросе, который сканирует всю таблицу / индекс данные SQL Server могут потерять позицию сканирования, или вы можете получить одну и ту же строку дважды. "
blockquote>
Вы можете использовать его, когда вы только читаете данные, и вам все равно, сможете ли вы вернуть данные, которые еще не были зафиксированы.
Это может быть быстрее на операция чтения, но на самом деле я не могу сказать, насколько.
В общем, я рекомендую не использовать ее - чтение недопустимых данных может быть немного запутанным в лучшем случае.
Я использую подсказку (nolock), особенно в базах данных SQLServer 2000 с высокой активностью. Я не уверен, что это необходимо в SQL Server 2005. Недавно я добавил этот намек на SQL Server 2000 по просьбе клиента DBA, потому что он замечал множество блокировок записей SPID.
Все, что я могу сказать, заключается в том, что использование подсказки НЕ повредило нам и, похоже, решило проблему блокировки. DBA у этого конкретного клиента в основном настаивал на том, что мы используем подсказку.
Кстати, базы данных, с которыми я имею дело, являются справочными системами корпоративных медицинских заявок, поэтому мы говорим о миллионах записей и 20 + таблицы во многих объединениях. Обычно я добавляю подсказку WITH (nolock) для каждой таблицы в объединении (если только это не производная таблица, и в этом случае вы не можете использовать этот конкретный намек)
NOLOCK
сSELECT
, вы рискуете возвращать одни и те же строки более одного раза (дублированные данные), если данные когда-либо вставлены (или обновлены) в таблицу при выполнении выбора. – Ian Boyd 19 September 2013 в 01:31