Итак, у меня есть простой процесс массовой вставки, чтобы взять данные из нашей промежуточной таблицы и перенести их в наш 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, так как данные уже отсортированы.
PAGEIOLATCH_EX
и ASYNC_IO_COMPLETION
указывают, что получение данных с диска в память занимает некоторое время. Это может быть индикатором проблемы с дисковой подсистемой или конфликтом памяти. Сколько памяти доступно SQL Server?
ASYNC_NETWORK_IO
означает, что SQL Server ожидал отправки строк клиенту куда-нибудь. Я предполагаю, что это показывает активность SSIS, потребляющую строки из промежуточной таблицы.