SQL和RAM ...如何在没有应用程序冻结的情况下更新2000条记录

时间:2011-07-25 10:07:24

标签: c# sql-server performance

我刚从WinForms应用程序运行查询,该应用程序为2k记录更新1个字段,但通常会更多。唯一的问题是该应用程序只是停止响应,更新10条记录大约需要30秒,这还不够好。我怎么搞砸了?

代码

using (SqlConnection conx = GetConnection())
{
  conx.Open();
  using (SqlCommand cmd = new SqlCommand())
  {
    cmd.Connection = conx;

    int counter = 0;
    foreach (DataRow row in mainResultsTable.Rows)
    {
       if(controlResult)
       {
         thisSerial = row[2].ToString();
         col = "[someColumn]";
       }
       cmd.CommandText = "UPDATE SomeTable$ SET [ToBeUpdated] = '" + DateTime.Now.ToString() + "' WHERE SomeColumn ='" + thisSerial.ToString() + "'";
       cmd.ExecuteNonQuery();
       counter++;
       if (counter == 10)
       {
         MessageBox.Show("10");
       }
    }
  }
}

PS。测试不是非常准确,我等待Messagebox弹出。

所以我最后做的是在SQL Server上创建一个临时表,导入上传数据并批量执行,在操作完成后删除临时表,这是否可取?

4 个答案:

答案 0 :(得分:3)

如果可能,您可以更好地运行一个SQL调用来更新所有记录,这将显着加快。如果您可以使用参数定义执行此操作的查询,则应该令人满意地更新。

或者,您必须考虑是否可以进行此操作,具体取决于您是否需要在完成之前完成此操作。

答案 1 :(得分:3)

我可以做一些事情,但最重要的是:

  1. 检查数据库服务器是否正常。也许某些进程停留在100%的处理器时间,并且您的数据库速度变慢。

  2. 检查数据库是否有锁。发布10个更新的时间不应超过几分之一秒,除非表的数量大约为数十亿。

  3. 检查表是否由SomeColumn列编入索引。这可以大大提高性能。

  4. 尝试从SQL Studio运行相同的10个语句,看看它们需要多长时间,以隔离问题的一面(客户端代码/数据库服务器)

  5. 尝试发送更少的更新语句,如果mainResultsTable有1.000.000行,您将发送1.000.000更新语句。如果使用SQL Server 2008,则可以使用带table-valued parameters的存储过程,否则,可以编译XML parameter,然后在服务器上解析它。您也可以使用Peter响应中的IN子句技巧,但我宁愿使用TVP或XML

  6. 尝试执行Application.DoEvents()以保持用户界面的响应能力(这通常是错误的方法,但它有时会快速有效地修复

  7. 使用BackgroundWorker将整个更新过程转换为另一个帖子。

  8. 除此之外,如果thisSerial属性为varchar,则此代码可能对二阶SQL注入开放。

答案 2 :(得分:2)

将所有连续出版物提取到列表中:

var serials = new List<string>();
foreach (DataRow row in mainResultsTable.Rows)
    serials.Add(row[2].ToString());

使用一个SQL查询更新所有行:

"UPDATE SomeTable SET [ToBeUpdated] = '" + DateTime.Now.ToString() + "' WHERE SomeColumn IN ('" + String.Join("','", serials) + "')";

答案 3 :(得分:1)

您必须拥有someColumn的索引。否则,UPDATE必须端到端扫描表以查找需要更新的行。

但是,接近在客户端逐个更新2k行并单独应用每个更新的问题从根本上是有缺陷的。这一次,它将是不成功的。但更重要的可能是不正确的。您正在更新的行是“实时”,并在您查看它们后进行更改。在服务器端将更新作为单个集合导向操作更好。如何做到这一点取决于我们无法猜测的一些因素只是看你的帖子。我建议你阅读Table-Valued Parameters in SQL Server 2008