У меня есть следующий (упрощенный) код, который я бы хотел оптимизировать для скорости:
long inputLen = 50000000; // 50 million
DataTable dataTable = new DataTable();
DataRow dataRow;
object[] objectRow;
while (inputLen--)
{
objectRow[0] = ...
objectRow[1] = ...
objectRow[2] = ...
// Generate output for this input
output = ...
for (int i = 0; i < outputLen; i++) // outputLen can range from 1 to 20,000
{
objectRow[3] = output[i];
dataRow = dataTable.NewRow();
dataRow.ItemArray = objectRow;
dataTable.Rows.Add(dataRow);
}
}
// Bulk copy
SqlBulkCopy bulkTask = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null);
bulkTask.DestinationTableName = "newTable";
bulkTask.BatchSize = dataTable.Rows.Count;
bulkTask.WriteToServer(dataTable);
bulkTask.Close();
Я уже использую SQLBulkCopy в попытке ускорить работу, но похоже, что присвоение значений самому DataTable оказывается медленным.
Я не знаю, как работают DataTables, поэтому мне интересно, создаю ли лишние накладные расходы, сначала создав многоразовый массив, а затем назначив его DataRow, а затем добавив DataRow в DataTable? Или же использовать DataTable не оптимально в первую очередь? Вход поступает из базы данных.
Мне мало что касается LOC, просто скорость. Может ли кто-нибудь дать совет по этому поводу?
Для такой большой таблицы вы должны использовать
public void WriteToServer(IDataReader reader)
метод.
Это может означать, что вам придется реализовать себе «поддельный» интерфейс IDataReader
с вашим кодом (если вы не получите данные из существующего IDataReader
), но таким образом вы получите «потоковое» из конца в конец , и избежит цикла 200 миллионов.
Вместо того, чтобы хранить огромную таблицу данных в памяти, я бы предложил внедрить IDataReader
который обслуживает данные в виде массовой копии. Это уменьшит необходимость держать все в памяти заранее и, таким образом, будет способствовать повышению производительности.