2013-04-02 2 views
4

Понимание окончательного решения - это бизнес-решение, каковы соображения точности между NOLOCK & READPAST работает в SQL 2008 R2? Прежде чем обсуждать изменения в бизнес-сфере, я хотел бы получить лучшее понимание.SQL 2008+ NOLOCK vs READPAST Соображения для точности отчетности

Я унаследовал несколько запросов, используемых для создания представлений данных для управленческой отчетности. 'WITH (NOLOCK)' используется либерально, но непоследовательно. Чтение данных происходит с производственного сервера широко используемого приложения, которое постоянно обновляется. Мы переносимся с сервера SQL 2005 на сервер SQL 2008 R2. Эти отчеты требуют, чтобы данные были более свежими, чем 24-часовые данные на сервере архива. Использование NOLOCK предполагает прошлое решение; существует вероятность конфликта, и это может привести к потере точности. Данные используются для заполнения информационных панелей для осознания человеком/принятия решений.

Все запросы являются SELECT, с доступом для чтения только для входа в режим просмотра данных. Большинство запросов - это одна таблица с несколькими объединениями по 2 и 3 таблицы. Учитывая низкий уровень соединений WITH(), кажется лучшим выбором, чем УРОВЕНЬ УРОВНЯ ИЗОБРАЖЕНИЯ СТАВКИ {}

Табличные подсказки (Transact-SQL) http://msdn.microsoft.com/en-us/library/ms187373.aspx (а также несколько вопросов о SO) говорят, что NOLOCK и/или READUNCOMMITTED вероятны чтобы иметь дублированные проблемы чтения, в дополнение к отсутствию заблокированных записей.

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

Существует хорошая статья Тима Chapman сравнивая два, но это было написано в 2007 году, большинство комментариев вращаются вокруг 2000 & 2005, с одним комментарием, указывающей READPAST является проблематичным в 2008 R2

Ссылки

Effect of NOLOCK hint in SELECT statements

When should you use "with (nolock)"

Using NOLOCK and READPAST table hints in SQL Server (By Tim Chapman)

Редакция:

Изоляция снимков предлагается в двух ответах ниже. Изоляция моментальных снимков зависит от настройки БД, этот Q/A https://serverfault.com/questions/117104/how-can-i-tell-if-snapshot-isolation-is-turned-on описывает, как определить, какие настройки установлены в базе данных. Теперь я знаю, что он отключен, я читаю отчеты из основной базы данных приложений. Изменение настройки не является опцией. + - допустимая погрешность в пару процентов допустима, воздействие приложения (OLTP) неприемлемо. Большинство простых запросов не требуют блокировки, но в некоторых крайних случаях требуется блокировка. С появлением выделения Snapshot для SQL 2005 в NOLOCK & мало информации о поведении READPAST в SQL 2008 или выше. Но они остаются моим единственным выбором.

+2

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

+0

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

ответ

2

Ответ на мой вопрос после стресс-тестирования с помощью SQLQueryStress http://www.datamanipulation.net/sqlquerystress/ (это замечательный инструмент, который чрезвычайно прост в использовании). Результаты SQLQueryStress протестированы против SQL Server Profiler; точность такая же, как у SQL Server Profiler, хотя прецессия - это два десятичных знака секунды меньше (но этого достаточно для этого теста).

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

После загрузки и ознакомления с SQLQueryStress я настроил простой «ReportQuery», чтобы действовать как ресурс. Он должен запустить 15 итераций с 15 потоками (225 запросов). Общее время работы составляет около 28 секунд, при этом среднее время итерации составляет 1,49 секунды.

Создал Add/Delete 'ApplicationQuery' для представления текущей активности приложения. Он настроен на запуск 2000 итераций с помощью 1 потока. Существуют две версии, с оператором select (выполняется 31 секунда) и без оператора select (выполняется 28 секунд). Они представляют собой нормальную активность приложения пикового времени.

Выполнено 10 тестовых прогонов каждой из трех версий «ReportQuery», чтобы определить, есть ли какое-либо преимущество в производительности между «с (nolock)», «с» (readpast) и без подсказок. Результаты не показывают существенной разницы, что ReportQuery работает постоянно примерно за 28 секунд со средним временем итерации 1,5 секунды.

Нет больших выбросов, поэтому решение опустить до 5 тестовых прогонов для следующих испытаний.

5 тестовых прогонов ApplicationQuery с помощью оператора select; с одной из трех версий «ReportQuery». В каждом из 15 итоговых тестов приложение ApplicationQuery запускается вручную, при этом ReportQuery запускается вручную сразу после. Этот сценарий представляет собой сложный запрос ресурса, который борется с текущими действиями приложений для ресурсов.

Повторный запуск тестов, но на этот раз использовался ApplicationQuery без оператора select.

Результаты: В каждом случае приложение ApplicationQuery было отключено до почти никакого прогресса вперед, в то время как ReportQuery запускался.

В ReportQuery не было существенной потери производительности при борьбе за ресурсы с несколькими приложениями ApplicationQuery против базы данных.

Приложение ApplicationQuery могло выполнять запросы параллельно с ReportQuery, но прогресс был очень медленным, в то время как конкуренция за ресурсы. По существу общее время запуска запросов на добавление/удаление приложений 2000 было увеличено на время, используемое ReportQuery.

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

«ReportQuery»

select 
ID 
, [TABLE_NAME] 
, NUMBER 
, FIELD 
, OLD_VALUE 
, NEW_VALUE 
, SYSMODUSER 
, SYSMODTIME 
, SYSMODCOUNT 

from dbo.UPMCINCIDENTMGMTAUDITRECORDSM1 

where Number like '%' 
or NUMBER like '2010-01-01' 

«ApplicationQuery» (с Select Заявления)

select * 

from dbo.UPMCINCIDENTMGMTAUDITRECORDSM1 
where FIELD = 'JJTestingPerformance' 


insert into dbo.UPMCINCIDENTMGMTAUDITRECORDSM1 (ID 
, [TABLE_NAME] 
, NUMBER 
, FIELD 
, OLD_VALUE 
, NEW_VALUE 
) 

values ('Test+Time' 
, 'none' 
, 'tst01' 
, 'JJTestingPerformance' 
, 'No Value' 
, 'Test' 
) 

delete from dbo.UPMCINCIDENTMGMTAUDITRECORDSM1 

where FIELD = 'JJTestingPerformance' 

«ApplicationQuery» (без Select Заявления)

insert into dbo.UPMCINCIDENTMGMTAUDITRECORDSM1 (ID 
, [TABLE_NAME] 
, NUMBER 
, FIELD 
, OLD_VALUE 
, NEW_VALUE 
) 

values ('Test+Time' 
, 'none' 
, 'tst01' 
, 'JJTestingPerformance' 
, 'No Value' 
, 'Test' 
) 

delete from dbo.UPMCINCIDENTMGMTAUDITRECORDSM1 

where FIELD = 'JJTestingPerformance' 

Screen shot of test results

8

Лучшее решение, заслуживающее внимания, позволяет выполнить ЧИТАЕМОЕ СООБЩЕНИЕ для самой базы данных. Это использует управление версиями в tempdb для захвата состояния таблицы в начале транзакции.

Существует очень хорошо читать по различным аспектам NOLOCK, READPAST и т.д., в http://www.brentozar.com/archive/2013/01/implementing-snapshot-or-read-committed-snapshot-isolation-in-sql-server-a-guide/

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

WITH (READPAST) будет пропускать любые записи, которые обновляются или вставляются во время чтения из таблицы. Ни один из вариантов не подходит в загруженной базе данных.

В свете недавнего изменения вашего вопроса, в котором вы указываете, вы не можете изменить настройку базы данных для READ COMMITTED SNAPSHOT, возможно, вам стоит рассмотреть возможность использования хранимой процедуры для сбора данных для ваших отчетов и установки уровня изоляции транзакций в начале сохраненная процедура с использованием SET TRANSACTION ISOLATION LEVEL SNAPSHOT;. Для этого вам нужно будет изменить параметр базы данных «разрешить изоляцию моментальных снимков».

С SQL Server Books Online:

СНАПШОТ

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

За исключением случаев, когда база данных восстанавливается, транзакции SNAPSHOT не запрашивают блокировки при чтении данных. Данные чтения транзакций SNAPSHOT не блокируют другие транзакции от записи данных. Транзакции, записывающие данные, не блокируют транзакции SNAPSHOT от чтения данных.

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

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

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

Сделка, выполняющаяся под уровнем изоляции SNAPSHOT, может просматривать изменения, сделанные этой транзакцией. Например, если транзакция выполняет UPDATE в таблице, а затем выдает инструкцию SELECT в той же таблице, измененные данные будут включены в результирующий набор.

+2

Спасибо за ссылку, я сейчас поглощаю. –

+0

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

3

NOLOCK может привести к чтению повторяющихся данных, данных, которые должны быть пропущены, и к запросу действительно отказаться с сообщением об ошибке (что-то с «перемещением данных»).

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

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

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

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

+0

+1 для изоляции моментальных снимков –

Смежные вопросы