Я смотрю, есть ли что-то, что я могу сделать, чтобы значительно ускорить вставку ADO.net, но все же делаю вставку с помощью нескольких команд INSERT INTO table values (...)
. Я размещаю данные из проприетарных, не запрашиваемых файлов базы данных в SQL Server. Утилита, которую я пишу, будет использоваться из скрипта.
Я понимаю, что для достижения наилучшей производительности, INSERT INTO
- это неправильный путь, но я все же хотел бы знать, есть ли какой-то подход ADO.net или SQL Server, который я должен попробовать.
Я подключаюсь к SQL Server 2008 с помощью C # 2010. Я сравниваю свою производительность с неуправляемым кодом, вставляющим данные в SQL Server, используя драйвер ODBC 3.5 от Microsoft с Native Client 10.0. Разумно ли ожидать, чтобы иметь возможность соответствовать производительности ODBC?
Таблица назначения не имеет индексов или других ограничений, триггеров, это просто промежуточная таблица. Исходные данные - это набор нестандартных типов данных, которые мне нужно преобразовать в строки.
Разобравшись до соответствующей детали, мой код:
SqlCommand comm = new SqlCommand;
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
SqlTransaction insertTransaction = conn.BeginTransaction();
comm.Connection = conn;
comm.Transaction = insertTransaction;
while(buffer.ReadNext()) // fill a buffer that I use to make my query
{
// form my insert statement and assign it
// It looks like: INSERT INTO myTable VALUES (5,'2016-02-16',NULL,3)
// A good fraction of the data is numeric with decimal points. A good
// fraction is dates. The parsing and string building,
// extravagantly inefficient as it is, is not the culprit.
// The INSERT INTO does not specify the column names
comm.CommandText = myStatement;
if (comm.ExecuteNonQuery() != 1) {throw...}
}
insertTransaction.commit;
Я пытался указать разные уровни изоляции; Я не смог указать .Snapshot
(не хочу настраивать целевую базу данных, чтобы разрешить это). Ничто не имело большого значения.
Если я закомментирую comm.ExecuteNoQuery
, чтобы позволить ему просто вращаться, формируя INSERT-атрибуты, он идет так быстро, как мне кажется, если бы он действительно что-то делал. Если я раскомментирую это, это займет примерно в 8 раз больше времени, чем я думаю. «Откуда берется« в 8 раз больше »? ты спрашиваешь. Что ж, я делаю аналогичную операцию (сквозная идентичная операция) с Pervasive Data Integrator (например, Data Junction). Из диагностики, когда происходит сбой Pervasive, я считаю, что программа делает вставки, используя последовательный INSERT INTO
заявления, как и я. Он идет примерно в 8 раз быстрее, чем моя программа, только на очень небольшую величину медленнее, чем формирование моих операторов INSERT INTO
, если я их не выполняю.
Pervasive Integrator добавляет ODBC, а драйвер ODBC настроен на использование собственного клиента Sql. И Data Integrator не является программным обеспечением .Net. Я на самом деле не пытался пройти через
ODBC, я думаю, что попробую сейчас, когда это произойдет со мной, но моя цель - избавиться от ODBC, чтобы это было просто точка данных, а не решение, даже если это быстрее.
Я попытался заполнить таблицу данных с целью массовой вставки, но заполнение набора данных также заняло слишком много времени. Я предполагаю, что какой-то альтернативный способ, который использует массовую вставку, является самым быстрым способом заставить его работать, но даже если я в конечном итоге перестану использовать мой INSERT INTO
подход, мне любопытно, почему это занимает намного больше времени (чем, я думаю, должно)
Операторы вставки довольно длинные, в моей таблице ~ 350 столбцов.