Массовые обновления и частота коммитов в SQL Server - PullRequest
3 голосов
/ 10 февраля 2009

Основой моей базы данных в основном является Oracle, но недавно я помогал с работой над SQL Server. Моя группа унаследовала некоторые пакеты SQL Server DTS, которые ежедневно загружают и обновляют большие объемы данных. В настоящее время он работает в SQL Server 2000, но вскоре будет обновлен до SQL Server 2005 или 2008. Массовые обновления выполняются слишком медленно.

Одна вещь, которую я заметил в коде, это то, что некоторые большие обновления выполняются в процедурном коде в циклах, так что каждый оператор обновляет только небольшую часть таблицы в одной транзакции. Это надежный метод для обновления на сервере SQL? Блокировка одновременных сеансов не должна быть проблемой, потому что пользовательский доступ к таблицам отключен во время массовой загрузки. Я гулял по некоторым и обнаружил, что некоторые статьи предполагают, что выполнение этого способа экономит ресурсы, и что ресурсы высвобождаются каждый раз, когда происходит обновление, что приводит к большей эффективности. В Oracle это, как правило, плохой подход, и я успешно использовал отдельные транзакции для очень больших обновлений в Oracle. Частые коммиты замедляют процесс и используют больше ресурсов в Oracle.

Мой вопрос заключается в том, что для массовых обновлений в SQL Server, как правило, целесообразно использовать процедурный код и фиксировать много операторов SQL или использовать один большой оператор для полного обновления?

Ответы [ 4 ]

2 голосов
/ 27 мая 2009

Извините, ребята,

Никто из вышеперечисленных не ответит на вопрос. Это всего лишь примеры того, как вы можете делать вещи. Ответ таков: при частых фиксациях используется больше ресурсов, однако журнал транзакций не может быть усечен до точки фиксации. Таким образом, если ваша отдельная охватывающая транзакция очень велика, это приведет к увеличению журнала транзакций и, возможно, к фрагментации, которая, если ее не обнаружить, вызовет проблемы позже. Кроме того, в ситуации отката длительность обычно в два раза больше, чем исходная транзакция. Поэтому, если ваша транзакция завершится неудачей через полчаса, откат займет 1 час, и вы не сможете остановить ее: -)

Я работал с SQL Server 2000/2005, DB2, ADABAS, и вышеизложенное верно для всех. Я действительно не понимаю, как Oracle может работать по-другому.

Возможно, вы могли бы заменить T-SQL командой bcp, и там вы можете установить размер пакета без необходимости его кодирования.

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

Держитесь подальше от снимков. Снимок только увеличит количество операций ввода-вывода и конкурирует за операции ввода-вывода и процессора

1 голос
/ 10 февраля 2009

В общем, я считаю, что лучше обновлять в пакетном режиме - обычно в диапазоне от 100 до 1000. Все зависит от того, как структурированы ваши таблицы: внешние ключи? Триггеры? Или просто обновление необработанных данных? Вам нужно поэкспериментировать, чтобы увидеть, какой сценарий подходит вам лучше всего.

Если я использую чистый SQL, я сделаю что-то вроде этого, чтобы помочь управлять ресурсами сервера:

SET ROWCOUNT 1000
WHILE 1=1 BEGIN
    DELETE FROM MyTable WHERE ...
    IF @@ROWCOUNT = 0
        BREAK
END
SET ROWCOUNT 0

В этом примере я очищаю данные. Это будет работать только для ОБНОВЛЕНИЯ, если вы можете ограничить или иным образом выборочно обновить строки. (Или вставьте только число хххх строк во вспомогательную таблицу, к которой вы можете присоединиться.)

Но да, старайтесь не обновлять xx миллионов строк одновременно. Это займет вечность, и если произойдет ошибка, все эти строки будут откатаны (что потребует дополнительных навсегда.)

0 голосов
/ 10 февраля 2009

При переходе на SQL Server 2005 или 2008 вам необходимо будет повторить все эти пакеты DTS в службах SSIS. Я думаю, вы будете приятно удивлены, увидев, насколько быстрее может быть SSIS.

В общем, в SQL Server 2000 вы хотите запускать вещи в пакетах записей, если весь набор слишком долго связывает таблицу. Если вы запускаете пакеты ночью, когда система бесполезна, возможно, вам удастся избежать вставки всего набора данных на основе набора. Строка за строкой всегда самый медленный метод, поэтому избегайте его, если это возможно (особенно, если все вставки строки-строки-строки находятся в одной гигантской транзакции!). Если у вас есть 24-часовой доступ без простоя, вам почти наверняка придется работать партиями.

0 голосов
/ 10 февраля 2009

Ну, все зависит.

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

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

Работа в пакетном режиме - это общая практика, которая довольно часто используется в SQL Server (когда он не находится в режиме изоляции моментальных снимков) для повышения параллелизма и избежания огромных откатов транзакций из-за взаимных блокировок (при обновлении 10 миллионов вы, как правило, получаете много тупиковых ситуаций) таблица строк, которая активна).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...