0

过去使用 ADO,我们使用 GetRows() 拉回一个数组并循环遍历它,因为它比使用 rs.MoveNext 遍历记录要快。我正在编写一个应用程序,它可以拉回 50 万行并将它们写到一个文件中。从 SQL 中提取数据大约需要 3 分钟,但将其写入 CSV 则需要另外 12 分钟。从它的外观来看,这是因为我正在循环一个 SqlDataReader。什么是更快的选择?

请记住,我不知道 SQL 结构会是什么样子,因为它正在调用一个报告表,该表告诉我的应用程序应该调用什么查询。我查看了使用 linq 并返回一个数组,但这需要知道结构,所以这不起作用。

注意下面的代码,case 语句有很多情况,但是为了节省空间,我把它们都删除了,除了一个。

StringBuilder rowValue = new StringBuilder();
SqlDataReader reader = queryData.Execute(System.Data.CommandType.Text, sql, null);

//this is to handle multiple record sets
while (reader.HasRows)
{
  for (int i = 0; i < reader.FieldCount; i++)
  {
    if (rowValue.Length > 0)
        rowValue.Append("\",\"");
    else
        rowValue.Append("\"");
    rowValue.Append(reader.GetName(i).Replace("\"", "'").Trim());
  }
  rowValue.Append("\"" + Environment.NewLine);

  File.AppendAllText(soureFile, rowValue.ToString());

  while (reader.Read())
  {
    rowValue = new StringBuilder();

    for (int i = 0; i < reader.FieldCount; i++)
    {
      String value = "";
      switch (reader.GetFieldType(i).Name.ToLower())
      {
          case "int16":
              value = reader.IsDBNull(i) ? "NULL" : reader.GetInt16(i).ToString();
              break;
      }

      if (rowValue.Length > 0)
          rowValue.Append("\",=\"");               //seperate items
      else
          rowValue.Append("\"");                  //first item of the row.

      rowValue.Append(value.Replace("\"", "'").Trim());
    }
    rowValue.Append("\"" + Environment.NewLine);    //last item of the row.

    File.AppendAllText(soureFile, rowValue.ToString());
    }  

  //next record set
  reader.NextResult();

  if (reader.HasRows)
    File.AppendAllText(soureFile, Environment.NewLine);
}

reader.Close();
4

1 回答 1

2

这里的问题几乎可以肯定是您正在调用File.AppendAllText()每一行。由于AppendAllText每次调用文件时都会打开、写入和关闭文件,因此它会变得非常慢。

更好的方法是使用该AppendText()方法或显式StreamWriter.

于 2013-03-04T22:46:28.903 回答