来自C#/ ASP.NET的缓慢,大型SQL查询

wma*_*ard 0 c# sql sqldatareader

可能重复:
如何在c#中有效地从SQL datareader写入文件?

我目前正在尝试创建一个使用只读访问权限的Web应用程序,以允许用户从我们的数据库下载大文件.有问题的表中有400,000条记录,导出时会生成50 MB的.csv文件.

在SQL服务器上运行语句"SELECT*FROM [table]"需要大约7秒,而从我的Web应用程序(托管在不同服务器上)执行此操作大约需要33秒.这是将所有数据读入System.Data.SqlClient.SqlDataReader对象.

我的问题是我无法将我的SqlDataReader转换为.csv文件.将SqlDataReader的每一行转换为字符串并逐行将该字符串输出到文件大约需要2个小时,这是不可接受的.下面是我用来在Web应用程序的服务器上创建文件的代码:

    while (rdr.Read())
    {
        string lineout = "";
        for (int index = 0; index < rdr.FieldCount; index++)
            lineout += rdr[index].ToString().Replace(',', ' ') + ',';
        write(lineout, filename); //uses StreamWriter.WriteLine()
    }
Run Code Online (Sandbox Code Playgroud)

一定有更好的方法.我环顾四周,看到了很多建议,基本上建议你做上面的事情来创建一个文件.这适用于较小的表,但不是我们每天使用的两个非常大的表.任何人都可以给我一个正确的方向吗?

Dan*_*ley 5

您可以尝试lineout使用StringBuilder而不是手动连接字符串来构建您:

//you can test whether it makes any difference in performance declaring a single
//StringBuilder and clearing, or creating a new one per loop
var sb = new StringBuilder();

while (rdr.Read())
{
    for (int index = 0; index < rdr.FieldCount; index++)
        sb.Append(rdr[index].ToString().Replace(',', ' ').Append(',');

    write(sb.ToString(), filename); //uses StreamWriter.WriteLine()
    sb.Clear();
}
Run Code Online (Sandbox Code Playgroud)

或者尝试直接写入文件并避免先在内存中生成每一行:

//assume a StreamWriter instance has been created called sw...
while (rdr.Read())
{
    for (int index = 0; index < rdr.FieldCount; index++)
    {
        sw.Write(rdr[index].ToString().Replace(',', ' ');
        sw.WriteLine(",");
    }
}

//flush and close stream
Run Code Online (Sandbox Code Playgroud)