【问题标题】:Edit Large Datatable Performance Issue编辑大型数据表性能问题
【发布时间】:2013-09-18 05:46:22
【问题描述】:

我有一个包含大约 10 万条记录的数据表。 Datatable 有多个包含一些整数值的列。我需要添加这些整数值并将其写入列Total CountCommon Count。我正在使用以下代码,但大约需要 10-15 秒。我怎样才能有效地做到这一点??

编辑部分开始

cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@pudTowerList", SqlDbType.VarChar, 8000).Value = cellId;
cmd.Parameters.Add("@pudTowerCol", SqlDbType.VarChar, 8000).Value = cellIdCol;
sqlCon.Open();
SqlDataReader dr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dr);
SqlCon.Close();
cmd.Dispose();

编辑部分结束

在这里我编辑这个数据表,然后在最后绑定到 gridview

 foreach (DataRow drow in dt.Rows)
   {
      int nTotalCount = 0;
      int nCommonCount = 0;
      for (int i = 2; i < nColumnCount; i++)
      {
         nTotalCount += int.Parse(drow[i].ToString());
         if (int.Parse(drow[i].ToString()) != 0)
         {
            nCommonCount += 1;
         }
      }
       drow["Total Count"] = nTotalCount; // On commenting this lines it runs fast
       drow["Common Count"] = nCommonCount; // On commenting this lines it runs fast
    }             

【问题讨论】:

  • 但是如果它是只读的.. 我怎么能编辑值
  • @Anirudh 我不会在数据库中插入总数。这仅用于显示网格中的值。请查看我编辑的问题,完整显示我在做什么
  • 据我了解,nTotalCount 是所有列值的总和,nCommonCount 是第一个。不为零的列值。我理解正确了吗?请澄清。

标签: c# winforms datatable


【解决方案1】:

想办法替代

int.Parse(drow[i].ToString());

直接投射:

(int)drow[i];

如果单元格值中没有整数,请尽你所能将它们放在那里。

除此之外 - 留意任何可能因列值更新而触发的事件 - 也许这就是让您放慢速度的原因。

另一种思路:使用SQL计算列值!

【讨论】:

  • 你的意思是程序将计算值返回给我
【解决方案2】:

我建议不要在c#中执行这么繁重的任务,而是从它自己的sql server返回这个计算值(尝试在存储过程中操作这个繁重的数据)并返回计算值。

【讨论】:

    【解决方案3】:

    您可以在 SQL 中计算,而不是在 C# 中计算,如下所示:

    SELECT Id,Col1,Col2,Col3, 
    Col1+Col2+Col3 as TotalCount,
    SIGN(Col1)+SIGN(Col2)+SIGN(Col3) as CommonCount
    FROM test.SO1;
    

    如果您必须使用 C#,我可以建议的直接改进是将两个 Parse() 调用替换为一个 Convert() 调用。您还将避免两次 ToString() 调用。试试这个:

    替换

    nTotalCount += int.Parse(drow[i].ToString());
    if (int.Parse(drow[i].ToString()) != 0)
    {
        nCommonCount += 1;
    }
    

    有了这个

    var val = Convert.ToInt32(drow[i]);
    if(val != 0)
    {
        nTotalCount += val;
        nCommonCount++;
    }
    

    【讨论】:

    • 性能不影响计算总计数值和公共计数值,但在我们将值分配给数据行的行。如果我评论这两行,它实际上以相当令人满意的性能运行
    • 上面提到的 c# 代码的区别是在我的测试中提高了 40-60% 的性能。但是正如您所说,如果分配值是瓶颈,我可以建议使用 TPL/多线程,但我不确定在这种情况下它是否会对您有所帮助。您能否分享更多信息或向我们展示您如何向 DataTable 添加列的代码?
    • 我已经在其中展示了我的问题.. 我正在通过 datareader 填充数据表
    • 谢谢拉吉夫。但我想了解的是,“Total Count”和“Common Count”列是来自 StoredProc 本身还是您使用的是 dt.Columns.Add(new DataColumn() { ColumnName = "Col1", DataType = typeof(int) } );将这些列添加到 DataTable?
    • 它们来自存储过程,但默认值为 '0'
    猜你喜欢
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 2016-11-04
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多