我的代码中有这样的东西(.Net 2.0,MS SQL)
SqlConnection connection = new SqlConnection(@"Data Source=localhost;Initial Catalog=DataBase;Integrated Security=True"); connection.Open(); SqlCommand cmdInsert = connection.CreateCommand(); SqlTransaction sqlTran = connection.BeginTransaction(); cmdInsert.Transaction = sqlTran; cmdInsert.CommandText = @"INSERT INTO MyDestinationTable" + "(Year, Month, Day, Hour, ...) " + "VALUES " + "(@Year, @Month, @Day, @Hour, ...) "; cmdInsert.Parameters.Add("@Year", SqlDbType.SmallInt); cmdInsert.Parameters.Add("@Month", SqlDbType.TinyInt); cmdInsert.Parameters.Add("@Day", SqlDbType.TinyInt); // more fields here cmdInsert.Prepare(); Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read); StreamReader reader = new StreamReader(stream); char[] delimeter = new char[] {' '}; String[] records; while (!reader.EndOfStream) { records = reader.ReadLine().Split(delimeter, StringSplitOptions.None); cmdInsert.Parameters["@Year"].Value = Int32.Parse(records[0].Substring(0, 4)); cmdInsert.Parameters["@Month"].Value = Int32.Parse(records[0].Substring(5, 2)); cmdInsert.Parameters["@Day"].Value = Int32.Parse(records[0].Substring(8, 2)); // more here complicated stuff here cmdInsert.ExecuteNonQuery() } sqlTran.Commit(); connection.Close();
使用cmdInsert.ExecuteNonQuery()注释掉此代码的执行时间不到2秒.使用SQL执行需要1分20秒.有大约0.5百万的记录.表之前已清空.具有类似功能的SSIS数据流任务大约需要20秒.
BULK INSERT 是不是一种选择(见下文).在导入过程中,我做了一些奇特的东西.
我的测试机器是Core 2 Duo,内存为2 GB.
在查看任务管理器时,CPU尚未完全直到最后.IO似乎也没有得到充分利用.
Schema很简单就像地狱一样:一个表以AutoInt作为主要索引,少于10个整数,微小的整数和字符(10).
在这里得到一些答案后,我发现可以从内存中执行批量复制!我拒绝使用批量复制,因为我认为必须从文件中完成...
现在我使用它,它需要20秒(像SSIS任务)
DataTable dataTable = new DataTable(); dataTable.Columns.Add(new DataColumn("ixMyIndex", System.Type.GetType("System.Int32"))); dataTable.Columns.Add(new DataColumn("Year", System.Type.GetType("System.Int32"))); dataTable.Columns.Add(new DataColumn("Month", System.Type.GetType("System.Int32"))); dataTable.Columns.Add(new DataColumn("Day", System.Type.GetType("System.Int32"))); // ... and more to go DataRow dataRow; object[] objectRow = new object[dataTable.Columns.Count]; Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read); StreamReader reader = new StreamReader(stream); char[] delimeter = new char[] { ' ' }; String[] records; int recordCount = 0; while (!reader.EndOfStream) { records = reader.ReadLine().Split(delimeter, StringSplitOptions.None); dataRow = dataTable.NewRow(); objectRow[0] = null; objectRow[1] = Int32.Parse(records[0].Substring(0, 4)); objectRow[2] = Int32.Parse(records[0].Substring(5, 2)); objectRow[3] = Int32.Parse(records[0].Substring(8, 2)); // my fancy stuf goes here dataRow.ItemArray = objectRow; dataTable.Rows.Add(dataRow); recordCount++; } SqlBulkCopy bulkTask = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null); bulkTask.DestinationTableName = "MyDestinationTable"; bulkTask.BatchSize = dataTable.Rows.Count; bulkTask.WriteToServer(dataTable); bulkTask.Close();
Adam Hughes.. 9
不要单独插入每个记录,请尝试使用SqlBulkCopy类一次批量插入所有记录.
创建一个DataTable并将所有记录添加到DataTable,然后使用SqlBulkCopy.WriteToServer一次批量插入所有数据.
不要单独插入每个记录,请尝试使用SqlBulkCopy类一次批量插入所有记录.
创建一个DataTable并将所有记录添加到DataTable,然后使用SqlBulkCopy.WriteToServer一次批量插入所有数据.