Я разработчик отчетов, который хочет сделать мои запросы максимально эффективными. Раньше я работал с администратором базы данных, который говорил мне - я считаю, потому что я всегда имел дело с отчетами на производственном сервере - для использования NOLOCK
в каждом отдельном запросе.
Теперь я работаю с администратором базы данных, который запретил работу NOLOCK
при любых обстоятельствах - даже когда мой отчет (из-за значительного отсутствия индексов в нескольких таблицах) останавливает репликацию и обновления системы. На мой взгляд, в этом случае NOLOCK
было бы хорошо.
Поскольку большая часть моего обучения SQL проходила с разными администраторами баз данных с совершенно разными мнениями, я хотел спросить об этом у самых разных администраторов баз данных.
источник
Ответы:
Если ваш отчет блокирует обновления, то ваш администратор базы данных прав: вы не должны его использовать
NOLOCK
. Сам факт того, что есть конфликты является явным признаком того, что , если вы бы использовать грязное чтение вы получите неправильные отчеты.На мой взгляд, всегда есть лучшие альтернативы, чем
NOLOCK
:SET TRANSACTION ISOLATION LEVEL
, а не подсказку запроса. Позже будет проще исправить уровень изоляции, а не изменять каждый запрос.источник
Это не всегда плохо.
Конечно, это позволяет вам читать непереданные значения (которые могут быть откатаны и, следовательно, никогда не существовали логически), а также разрешать такие явления, как считывание значений несколько раз или не делать это вообще.
Единственные уровни изоляции, которые гарантируют, что вы не столкнетесь с такими аномалиями, - это сериализуемый / снимок. При повторяемом чтении значения могут быть пропущены, если строка перемещена (из-за обновления ключа) до того, как сканирование достигнет этой строки, при подтверждении прочитанного значения могут быть прочитаны дважды, если обновление ключа вызывает перемещение ранее прочитанной строки.
Эти проблемы, скорее всего, возникнут в
nolock
связи с тем, что, по умолчанию, на этом уровне изоляции он будет использовать упорядоченное сканирование при выделении, когда он оценивает, что нужно прочитать более 64 страниц . Наряду с категорией проблем, возникающих при перемещении строк между страницами из-за обновлений индексного ключа, эти упорядоченные сканирования размещения также уязвимы для проблем с разбиением страниц (где строки могут быть пропущены, если вновь выделенная страница находится в файле раньше, чем точка уже отсканировано или прочитано дважды, если уже отсканированная страница разделена на более позднюю страницу в файле).По крайней мере, для простых запросов (для одной таблицы) можно отказаться от использования этих проверок и получить упорядоченное сканирование по ключу
nolock
, просто добавивORDER BY index_key
к запросу так, чтобыOrdered
свойствоIndexScan
is былоtrue
.Но если ваше приложение для составления отчетов не нуждается в абсолютно точных цифрах и может допустить большую вероятность таких несоответствий, это может быть приемлемым.
Но, конечно, вам не следует бросать это на все запросы в надежде, что это волшебная «турбо» кнопка. Помимо большей вероятности обнаружения аномальных результатов на этом уровне изоляции или вообще без результатов (ошибка «Не удалось продолжить сканирование с NOLOCK из-за перемещения данных»), существуют даже случаи, когда производительность с
nolock
может быть намного хуже .источник
Ваши клиенты терпят противоречивые результаты в отчетах? Если ответ «нет», вы не должны использовать NOLOCK - вы можете получить неверные результаты при одновременном использовании. Я написал несколько примеров здесь , здесь и здесь . В этих примерах показаны противоречивые выходные данные в режимах READ COMMITTED и REPEATABLE READ, но вы также можете настроить их и получить неверные результаты с NOLOCK.
источник
Если это так, то у вас есть еще один возможный вариант:
вместо того, чтобы выполнять запросы в производственной базе данных и возиться с блокировками
NOLOCK
, вы можете запускать свои отчеты из копии производственной базы данных.Вы можете настроить его так, чтобы он автоматически восстанавливался из резервной копии каждую ночь .
Судя по всему, ваши отчеты работают на серверах на сайтах клиентов, поэтому я не знаю, будет ли это целесообразным решением для вас.
(но опять же ... в любом случае они должны иметь резервные копии, так что все, что вам нужно, это немного места на сервере для их восстановления)
Я - внутренний разработчик, так что это проще для меня, потому что я полностью контролирую серверы и базы данных.
Вы можете сделать это по крайней мере для отчетов, которые нуждаются только в данных вчера и старше. Возможно, некоторые отчеты должны будут оставаться в рабочей базе данных, но, по крайней мере, вы перенесете часть нагрузки в другую базу данных (или, что еще лучше, на другой сервер).
У меня такая же ситуация на работе:
мы используем копию производственной базы данных почти для всех отчетов, но есть несколько запросов, которые требуют сегодняшних данных.
источник