Итак, у меня есть простой процесс массовой вставки, чтобы взять данные из нашей промежуточной таблицы и перенести их в наш datamart.
Этот процесс представляет собой простую задачу потока данных с настройками по умолчанию для «Строк на пакет» и вариантами «tablock» и «no check ограничение».
Стол довольно большой. 587 162 986 с размером данных 201 ГБ и 49 ГБ индексного пространства. Кластерный индекс для таблицы.
CREATE CLUSTERED INDEX ImageData ON dbo.ImageData
(
DOC_ID ASC,
ACCT_NUM ASC,
MasterID ASC
)
И первичный ключ:
ALTER TABLE dbo.ImageData
ADD CONSTRAINT ImageData
PRIMARY KEY NONCLUSTERED
(
ImageID ASC,
DT_CRTE_DOC ASC
)
Теперь у нас возникла проблема, когда BULK INSERT
через SSIS работает невероятно медленно. 1 час, чтобы вставить миллион строк. Запрос, который заполняет таблицу, уже отсортирован, и выполнение запроса занимает менее минуты.
Когда процесс запущен, я вижу запрос, ожидающий вставки BULK, который занимает от 5 до 20 секунд и показывающий тип ожидания PAGEIOLATCH_EX
. Процесс может обрабатывать только INSERT
около тысячи строк одновременно.
Вчера при тестировании этого процесса в моей среде UAT я столкнулся с той же проблемой. Я запускал процесс несколько раз и пытался определить причину медленной вставки. Затем он неожиданно начал работать менее чем через 5 минут. Так что я запустил его еще несколько раз с тем же результатом. Кроме того, количество массовых вставок, которые ожидали 5 секунд или больше, сократилось с сотен до примерно 4.
Теперь это вызывает недоумение, потому что у нас не было большого падения активности.
Процессор во время продолжительности низкий.
Времена, когда он медленнее, кажется, что на диске меньше ожиданий.
Задержка диска фактически увеличивается в течение периода времени, в течение которого процесс выполнялся менее чем за 5 минут.
И IO был намного ниже во времена, когда этот процесс работает плохо.
Я уже проверил, и не было никакого увеличения файла, поскольку файлы заполнены только на 70%. В файле журнала еще осталось 50%. БД находится в режиме простого восстановления. БД имеет только одну файловую группу, но распределена по 4 файлам.
Так что мне интересно A: почему я видел такое большое время ожидания на этих массовых вставках. B: какая магия сделала это быстрее?
Примечание. Сегодня он снова работает как дерьмо.
ОБНОВЛЕНИЕ это в настоящее время разделено. Однако это делается в лучшем случае глупо.
CREATE PARTITION SCHEME [ps_Image] AS PARTITION [pf_Image]
TO ([FG_Image], [FG_Image], [FG_Image], [FG_Image])
CREATE PARTITION FUNCTION [pf_Image](datetime) AS
RANGE RIGHT FOR VALUES (
N'2011-12-01T00:00:00.000'
, N'2013-04-01T00:00:00.000'
, N'2013-07-01T00:00:00.000'
);
Это оставляет практически все данные в 4-м разделе. Тем не менее, так как все идет в одну файловую группу. Данные в настоящее время довольно равномерно распределены по этим файлам.
ОБНОВЛЕНИЕ 2 Это общие ожидания, когда процесс работает плохо.
Это ожидания в течение периода, когда я смог запустить процесс работает хорошо.
Подсистема хранения является локально подключенным RAID, SAN не задействована. Логи находятся на другом диске. Raid Controller - PERC H800 с размером кеша 1 ГБ. (Для UAT) Прод является PERC (810).
Мы используем простое восстановление без резервных копий. Восстанавливается из рабочей копии каждую ночь.
Мы также установили IsSorted property = TRUE
в SSIS, так как данные уже отсортированы.
ASYNC_NETWORK_IO
означает, что SQL Server ожидал отправки строк клиенту куда-нибудь. Я предполагаю, что это показывает активность SSIS, потребляющую строки из промежуточной таблицы.PAGEIOLATCH_EX
иASYNC_IO_COMPLETION
указывают, что получение данных с диска в память занимает некоторое время. Это может быть индикатором проблемы с дисковой подсистемой или конфликтом памяти. Сколько памяти доступно SQL Server?Ответы:
Я не могу указать на причину, но я считаю, что по умолчанию количество строк на пакет для операции BULK INSERT - «все». Установка ограничения в строках может сделать операцию более удобной для восприятия: вот почему это вариант. (Здесь и далее, я просматриваю документацию Transact-SQL «BULK INSERT», так что это может быть далеко для SSIS.)
Это даст эффект разделения операции на несколько пакетов по X строк, каждая из которых работает как отдельная транзакция. В случае ошибки завершенные пакеты останутся зафиксированными в таблице назначения, а остановленный пакет выполнит откат. Если это терпимо в том, что вы делаете, то есть вы можете запустить его позже и наверстать упущенное, попробуйте это.
Нет ничего плохого в том, чтобы иметь функцию секционирования, которая помещает все текущие вставки в один раздел таблицы, но я не понимаю, как это вообще полезно для секционирования с разделами в одной файловой группе. Использование datetime неэффективно и фактически не работает для datetime и «YYYY-MM-DD» без явной формулы CONVERT начиная с SQL Server 2008 (SQL может с радостью воспринимать это как YYYY-DD-MM: не шучу: не паникуйте, просто измените его на «ГГГГММДД», исправлено: или «КОНВЕРТ» (дата-время, «ГГГГ-ММ-ДДТ00: 00: 00», 126), я так думаю). Но я думаю, что использование прокси для значения даты (год как int или год + квартал) для разделения будет работать лучше.
Может быть, это дизайн, скопированный из другого места, или дублированный на нескольких датамарках. Если это - настоящий datamart, дамп из хранилища данных, чтобы дать менеджерам отделов некоторые данные, с которыми можно поиграть, которые не (вами) отправляются в другое место и, вероятно, доступны только для чтения, если речь идет о пользователях данных тогда мне кажется, что вы могли бы удалить функцию раздела - или - изменить ее, чтобы явно поместить все новые данные в четвертый раздел, несмотря ни на что, и никто бы не позаботился. (Возможно, вы должны проверить, что никто не заботится.)
Похоже на дизайн, в котором планируется удалить содержимое раздела 1 в будущем и создать еще один новый раздел для новых данных, но это не похоже на то, что здесь происходит. По крайней мере, такого не было с 2013 года.
источник
Иногда я сам видел такую же редкую крайнюю медлительность при вставках в большие разделенные таблицы. Вы пытались обновить статистику таблиц назначения и затем снова запустить? Экстремальное время ожидания может быть связано с плохой статистикой, и если обновление статистики было инициировано в какой-то момент во время тестирования, это объясняет увеличение скорости. Просто мысль и простой тест для проверки.
источник