Я сталкиваюсь с некоторыми узкими местами производительности с моим клиентом С#, вставляющим массивные данные в базу данных SQL Server 2005, и я ищу способы ускорения процесса.
Я уже использую SqlClient.SqlBulkCopy(который основан на TDS), чтобы ускорить передачу данных по проводу, что очень помогло, но я все еще ищу больше.
У меня есть простая таблица, которая выглядит так:
CREATE TABLE [BulkData](
[ContainerId] [int] NOT NULL,
[BinId] [smallint] NOT NULL,
[Sequence] [smallint] NOT NULL,
[ItemId] [int] NOT NULL,
[Left] [smallint] NOT NULL,
[Top] [smallint] NOT NULL,
[Right] [smallint] NOT NULL,
[Bottom] [smallint] NOT NULL,
CONSTRAINT [PKBulkData] PRIMARY KEY CLUSTERED
(
[ContainerIdId] ASC,
[BinId] ASC,
[Sequence] ASC
))
Я вставляю данные в куски, в среднем около 300 строк, где ContainerId и BinId являются постоянными в каждом фрагменте, а значение Sequence равно 0-n, а значения предварительно сортируются на основе первичного ключа.
Счетчик производительности% Disk time тратит много времени на 100%, поэтому ясно, что проблема с IO диска является основной проблемой, но скорости, которые я получаю, на несколько порядков ниже копии необработанного файла.
Помогает ли это, если я:
- Отбросьте ключ Primary, пока я вставляю и воссоздаю его позже.
- Вставляет во временную таблицу с той же схемой и периодически переносит их в основную таблицу, чтобы сохранить размер таблицы, где вставки происходят мелкие.
- Что-нибудь еще?
- Основываясь на ответах, которые я получил, позвольте мне немного пояснить:
Портман: Я использую кластерный индекс, потому что когда все данные импортируются, мне нужно будет последовательно получать данные в этом порядке. Мне особенно не нужен индекс, который будет там при импорте данных. Есть ли какое-либо преимущество в отношении наличия некластеризованного индекса PK при выполнении вставок, а не для ограничения ограничения для импорта?
Chopeen: данные генерируются удаленно на многих других машинах (мой SQL-сервер может обрабатывать только около 10 в настоящее время, но я хотел бы добавить больше). Нецелесообразно запускать весь процесс на локальной машине, потому что тогда ему придется обрабатывать в 50 раз больше входных данных для генерации вывода.
Jason: Я не делаю параллельных запросов к таблице во время процесса импорта, я попытаюсь удалить первичный ключ и посмотреть, помогает ли это.