c#花费数小时的时间来执行

时间:2010-08-31 12:59:12

标签: c#

以下代码需要花费数小时的时间来执行。我正在比较数据库中的每个字符串来计算N00,N01,N10,N11参数。 Temp1是类型字符串列表,它包含5000多个单词

foreach (string ri in temp1)
{
  for (int a3 = 0; a3 < ssl.Count; a3++)
  {
    //for (int tn = 0; tn < tempNam.Count ; tn++)
    //{
        try
        {
          SqlCommand cmd5 = new SqlCommand("select count(*) from sample s inner join   sample ss on ss.KeyWord='" + ri + "' and ss. " + ssl[a3].ToString() + "=0 and s.KeyWord='y' and s. " +  ssl[a3].ToString()+ "=0", con);
          int im = (int)cmd5.ExecuteScalar();
          if (im == 1)
          {
            gh += 1;
          }
          SqlCommand cmd6 = new SqlCommand("select count(*) from sample s inner join   sample ss on ss.KeyWord='" + ri + "' and ss. " + ssl[a3].ToString() + "=0 and s.KeyWord='y' and s. " + ssl[a3].ToString() + ">0", con);
          int im1 = (int)cmd6.ExecuteScalar();
          if (im1 == 1)
          {
            gh2 += 1;
          }
          SqlCommand cmd7 = new SqlCommand("select count(*) from sample s inner join   sample ss on ss.KeyWord='" + ri + "' and ss. " + ssl[a3].ToString() + ">0 and s.KeyWord='y' and s. " + ssl[a3].ToString() + "=0", con);
          int im2 = (int)cmd7.ExecuteScalar();
          if (im2 == 1)
          {
            gh3 += 1;
          }
          SqlCommand cmd8 = new SqlCommand("select count(*) from sample s inner join   sample ss on ss.KeyWord='" + ri + "' and ss. " + ssl[a3].ToString() + ">0 and s.KeyWord='y' and s. " + ssl[a3].ToString() + ">0", con);
          int im3 = (int)cmd8.ExecuteScalar();
          if (im3 == 1)
          {
            gh4 += 1;
          }
          if (a3 == (ssl.Count-1))
          {
            SqlCommand ins = new SqlCommand("update sample set N00=" + gh + " where KeyWord='" + ri + "'", con);
            ins.ExecuteNonQuery();
            gh = 0;
            SqlCommand ins1 = new SqlCommand("update sample set N01=" + gh2 + " where KeyWord='" + ri + "'", con);
            ins1.ExecuteNonQuery();
            gh2 = 0;
            SqlCommand ins2 = new SqlCommand("update sample set N10=" + gh3 + " where KeyWord='" + ri + "'", con);
            ins2.ExecuteNonQuery();
            gh3 = 0;
            SqlCommand ins4 = new SqlCommand("update sample set N11=" + gh4 + " where KeyWord='" + ri + "'", con);
            ins4.ExecuteNonQuery();
            gh4 = 0;
          }
        }
        catch (Exception ex)
        {
        }
      // }
    }
  }

  SqlCommand cmd1s = new SqlCommand("select KeyWord from sample", con);
  SqlDataAdapter da = new SqlDataAdapter(cmd1s);
  DataSet ds = new DataSet();
  da.Fill(ds, "sample");
  foreach (DataRow dr in ds.Tables[0].Rows)
  {
    string dd = dr["KeyWord"].ToString();
    if (dd != "y")
    {
      if (!li.Contains(dd))
      {
        li.Add(dd);
      }
    }
  }

3 个答案:

答案 0 :(得分:11)

Sample.KeyWord上添加索引。这会让这更加快速。

正如安东尼在下面的评论一样,这段代码存在很多错误。索引是我猜的占用时间最多的,但你也应该阅读这些主题:


在此处查看创建索引:http://msdn.microsoft.com/en-us/library/ms188783.aspx

答案 1 :(得分:3)

很抱歉,但您的代码很难理解它们的名称。 为了可读性,我重构了你的查询,转移到重用一个SqlCommand(如果你计算循环外的一个,总共两个)并删除额外的查询。

我猜测性能不佳与缺乏对象重用,查询重复工作有关,并且你可能会左右抛出异常而try / catch导致堆栈每次抛出都会展开例外!检查输出窗格以获取调试信息,或在行System.Diagnostics.Debug.Print(ex.ToString());上设置断点。 展开堆栈会导致执行时间停止。

我不确定你是否使用了糟糕的变量名,或者你是否对代码进行了模糊处理,但你真的应该在代码中加入有意义的变量名来获得帮助。

我很肯定你可以做更多的事情来优化你的代码,但我会重新使用SqlCommand,删除重复的查询,并首先正确处理你的异常处理。

foreach (string ri in temp1)
{
    for (int index = 0; index < ssl.Count; index++)
    {
        try
        {
            SqlCommand command;
            string query;

            query = string.Format("select count(*) from sample s inner join   sample ss on ss.KeyWord='{0}' and ss.{1}=0 and s.KeyWord='y' and s.{1}=0", ri, ssl[index].ToString());
            command = new SqlCommand(query, con);
            if ((int)command.ExecuteScalar() == 1)
            {
                gh++;
                gh3++;
            }

            query = string.Format("select count(*) from sample s inner join   sample ss on ss.KeyWord='{0}' and ss.{1}=0 and s.KeyWord='y' and s.{1}>0", ri, ssl[index].ToString());
            command = new SqlCommand(query, con);
            if ((int)command.ExecuteScalar() == 1)
            {
                gh2++;
                gh4++;
            }

            if (index == (ssl.Count-1))
            {
                query = string.Format("update sample set N00={0} where KeyWord='{1}'", gh.ToString(), ri);
                command = new SqlCommand(query, con);
                command.ExecuteNonQuery();
                gh = 0;

                query = string.Format("update sample set N01={0} where KeyWord='{1}'", gh2.ToString(), ri);
                command = new SqlCommand(query, con);
                command.ExecuteNonQuery();
                gh2 = 0;

                query = string.Format("update sample set N10={0} where KeyWord='{1}'", gh3.ToString(), ri);
                command = new SqlCommand(query, con);
                command.ExecuteNonQuery();
                gh3 = 0;

                query = string.Format("update sample set N11={0} where KeyWord='{1}'", gh4.ToString(), ri);
                command = new SqlCommand(query, con);
                command.ExecuteNonQuery();
                gh4 = 0;
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.Print(ex.ToString());
        }
    }
}

SqlCommand command = new SqlCommand("select KeyWord from sample", con);
SqlDataAdapter da = new SqlDataAdapter(command);
DataSet ds = new DataSet();
da.Fill(ds, "sample");
foreach (DataRow dr in ds.Tables[0].Rows)
{
    string KeywordCell = dr["KeyWord"].ToString();
    if (KeywordCell != "y")
    {
        if (!li.Contains(KeywordCell))
        {
            li.Add(KeywordCell);
        }
    }
}

答案 2 :(得分:1)

一旦你处理了其他人指出的更大问题,就会尝试一个次要的事情......

你通过内循环每次计算ssl[a3].ToString() 8次。对于a3的每个值,这是40,000次。您可以预先计算a3中每个项目的字符串值,并将它们存储在外部循环之前的List中。然后,不要在内循环中迭代索引关闭ssl,而是使用foreach对预先计算的字符串列表的值。

如果这样做,则需要将if (a3 == (ssl.Count-1))中的代码移出内循环到外循环的末尾。