Datatable Unpivot非常慢。 任何替代品?

我有一个有大约200行,大约200列以上的Excel工作表。 我需要unpivot这个Excel工作表,并将其插入到一个SQL服务器表。 我正在使用第三方excel api将excel工作表转换为ADO .Net Datatable。

原始数据表A 在这里输入图像说明

对于Unpivot操作,我将遍历原始的Datatable行和列,并将值分配给另一个DataTable,该DataTable已根据

数据表B未公开 在这里输入图像说明

获取新的DataTable填充后,我将使用数据表上的SQlBulkCopy()并将所有logging保存到SQLServer表。

我用于Un-Pivot操作的代码

//excelExport is the DataTable which stores the entire excel workSheet DataTable newDatatable = new DataTable(); //For Un-Pivoting newDatatable .Columns.Add(new DataColumn("EconomyID")); newDatatable .Columns.Add(new DataColumn("SystemLanguage")); newDatatable .Columns.Add(new DataColumn("VariableName")); newDatatable .Columns.Add(new DataColumn("VariableValue")); foreach (DataRow dr in excelExport.Rows) //excelExport is the original datatable { int colCount = 0; foreach (DataColumn dc in excelExport.Columns) { if (colCount >= 2) { DataRow dr2 = newDatatable.NewRow(); dr2["Economy"] = dr[1].ToString(); dr2["SystemLanguageID"] = dr[2].ToString(); dr2["VariableName"] = dc.ColumnName; dr2["VariableValue"] = dr[dc].ToString(); newDatatable.Rows.Add(dr2); } colCount++; } } 

现在的问题是,因为我原来的Datatable A有200多列(和200行)。 遍历每行并将值分配给另一个newDatatable需要10秒。 所以整个操作需要200行* 10秒…基本上永远(取决于excel / datatable中的列); 只是为了创buildnewDatatable。 是否有更有效的方式来处理这个Un-pivot操作。 我知道我们的SSIS包已经build立了excel到sqlserver的导入操作,但我们的要求是客户端应该能够将excel上传到系统中,并且过程必须是实时的。 有什么build议么?

200列的列索引查找可能是一个罪魁祸首。 你可以通过列号而不是string名来改变查找方式:

  foreach (DataColumn dc in excelExport.Columns) { if (colCount >= 2) { DataRow dr2 = newDatatable.NewRow(); dr2[0] = dr[1].ToString(); dr2[1] = dr[2].ToString(); dr2[2] = dc.ColumnName; dr2[3] = dr[colCount].ToString(); newDatatable.Rows.Add(dr2); } colCount++; } 

虽然这只是一个猜测。 我会投资一个好的分析工具来测量过程缓慢的地方,并首先修复最慢的部分。

构build一个新的DataTable比使用像Tuple这样的廉价结构更昂贵。

 var tuples = new List<Tuple<string, string, string, object>>(); foreach (DataRow dr in excelExport.Rows) { int colCount = 0; foreach (DataColumn dc in excelExport.Columns) { if (colCount >= 2) { tuples.Add(Tuple.Create(dr[1], dr[2], dc.ColumnName, (object)dr[colCount]) ); } colCount++; } } 

您也可以跳过ToString()调用,因为Tuple.Create将使用types推断来创build正确的元组。 也许最后一项可以有一个明确的types(不是object ),如果所有的值碰巧有相同的数据types,否则你需要(object)强制转换。