SQL Server - объединение больших таблиц без блокировки данных
-
18-09-2020 - |
Вопрос
У меня очень большой набор данных (~ 3 миллиона записей), которые должны быть объединены с обновлениями и новыми записями в ежедневном графике.У меня есть сохраненная процедура, которая фактически разбивает запись, установленную на 1000 блоков записи и использует команду MERGE
с TEMP-таблицами в попытке избежать блокировки живой таблицы, когда данные обновляются.Проблема в том, что она не помогает.Таблица все еще «блокируется» и наш веб-сайт, который использует данные, получает тайм-ауты при попытке доступа к данным.Я даже попытался разделить его на 100 записейков и даже попробовал генеракодицетагкод, чтобы посмотреть, поможет ли это сделать паузу между объединением кусков.Это все еще довольно вяло.
Я ищу любые предложения, лучшие практики или примеры о том, как объединить большие наборы данных, не блокируя таблицы.
Спасибо
Решение
Измените свой передний конец, чтобы использовать NOLOCK или прочитайте незарегистрированные при выполнении
Вы не можете Nolock Merge, INSERT или UPDATE, так как записи должны быть заблокированы, чтобы выполнить обновление.Тем не менее, вы можете нолить выбора.
Обратите внимание, что вы должны использовать это с осторожностью.Если грязные чтения в порядке, тогда идите вперед.Тем не менее, если чтения требуют обновленных данных, то вам нужно снизить другой путь и точно определить, почему объединение 3M записей вызывает проблему.
Я был бы готов сделать поспорьте, что большую часть времени потрачено на чтение данных с диска во время команды Merge и / или работает вокруг низких ситуаций памяти.Вам может быть лучше просто наполнить больше RAM в свой сервер базы данных.
Идеальная сумма будет иметь достаточно оперативной памяти, чтобы потянуть всю базу данных в память по мере необходимости.Например, если у вас есть база данных 4 ГБ, то убедитесь, что у вас есть 8 ГБ оперативной памяти .. в сервере X64, конечно.
Другие советы
Боюсь, что я совершенно противоположный опыт. Мы выполняли обновления и вставки, где исходная таблица имела только часть количества строк в качестве целевой таблицы, которая была в миллионах.
Когда мы объединили записи источника на столе по всему операционному окну, а затем выполняли слияние только один раз, мы увидели повышение производительности на 500%. Мое объяснение этого заключается в том, что вы платите за предельный анализ командной команды слияния только один раз вместо и снова в жесткой петле.
Кроме того, я уверен, что объединение 1,6 миллиона строк (источник) на 7 миллионов строк (цель), в отличие от 400 строк на 7 миллионов строк более 4000 различных операций (в нашем случае) использует возможности двигателя SQL Server намного лучше. Опять же, справедливая сумма работы находится в анализе двух наборов данных, и это делается только один раз.
Другой вопрос, который я должен спросить, это хорошо ли вы знаете, что команда Merge работает намного лучше с индексами как на источниках, так и на целевых таблицах? Я хотел бы направить вас к следующей ссылке:
http://msdn.microsoft.com /en-us/library/cc879317 (v=sql.100 ).aspx
Из личного опыта, главная проблема с Merge состоит в том, что поскольку он делает замок страницы, он исключает любую параллелизм в ваших вставках, направленных на таблицу. Поэтому, если вы пойдете по этой дороге, это фундаментальное, что вы пакетные обновления, которые будут ударены в таблицу в одном писателе.
Например: у нас была таблица, на которой вставка была сумасшедшая 0,2 секунды на вход, большая часть этого времени, казалось бы, потраченная впустую на транзакции, поэтому мы переключили это на использование Merge, и некоторые быстрые тесты показали, что это позволило нам Вставьте 256 записей за 0,4 секунды или даже 512 за 0,5 секунды, мы проверили это с генераторами нагрузки, и все, казалось, все было в порядке, пока он не достигнет производства, и все заблокировано в аду на замках страницы, что приводит к гораздо более низкой общей пропускной способности, чем отдельные вставки.
решение должно было не только разбивать записи от одного производителя в операции слияния, но и для пакетной партии от производителей, переходящих в отдельную БД в одном операции слияния через дополнительный уровень очереди (ранее также единое соединение За дБ, но с использованием MARS для переплетения всех производителей вызов на хранимую процедуру выполнять фактическую транзакцию слияния), таким образом мы могли обрабатывать много тысяч вкладышей в секунду без проблем.
Наличие Nolock Hints на всех ваших интерфейсах чтения - это абсолютный должен, всегда.