使用SqlDataReader同时读取多行(块读取)

时间:2016-02-02 17:26:29

标签: sql .net sqldatareader

我使用SqlDataReader来检索一些" SELECT"从DBMS查询。 到目前为止,我使用SqlDataReader.read()在结果集中逐个读取每一行,然后逐个处理它们。当结果集很大(意味着数百万行乘以数百列)时,使用.read()进行迭代非常慢。我问:有没有办法做一个"阻止"从SqlDataReader读取,意味着像SqlDataReader.read(100)这样的东西给了我一个结果集中接下来100行的数组?

我考虑过像DataTable.Load()那样在内存中加载所有结果集,但由于表的大小为几千兆字节,因此它不适合内存。

你会推荐什么? 非常感谢

示例代码:

TdConnection conn;
TdCommand cmd;
TdDataReader reader;
IAsyncResult res;

conn = new TdConnection(@"xxxx;");
conn.Open();

cmd = new TdCommand(q,conn);
res = cmd.BeginExecuteReader();

while (!res.IsCompleted);

reader = cmd.EndExecuteReader(res);
if (reader.HasRows)
{
    string sb;
    string currentout = "C:\file";
    string[] row = new string[reader.FieldCount];
    sb = "";
    for (int i = 0; i < reader.FieldCount; i++)
        row[i] = reader.GetName(i);

    sb = String.Concat(sb,String.Join("\t",row),"\r\n");

    File.WriteAllText(currentout,sb);

    sb = "";

    /* With a test query, the following commented "while" takes 5 minutes 
    /* to iterate over a dataset with 639967 rows x 63 columns (about 300MB)
    /* while(reader.Read());
    */

    /* With the same test query, the following "while block" takes 6 minutes
    /* to iterate over the same dataset AND writing it on a text file
    /* I conclude that I/O writing on text file is fast, and .Read() is very slow
    */
    while(reader.Read())
    {
        for (int i = 0; i < reader.FieldCount; i++)
                row[i] = reader.GetValue(i).ToString();

        sb = String.Concat(sb,String.Join("\t",row),"\r\n");

        if (sb.Length > 100000)
        {
            File.AppendAllText(currentout,sb);
            sb = "";
        }
    }
    File.AppendAllText(currentout,sb);
}

reader.Close();
reader.Dispose();
cmd.Dispose();
conn.Close();

&#34; Td&#34;组件是.NET的Teradata DBMS接口(但它们的行为就像&#34; SQL&#34;组件)。

1 个答案:

答案 0 :(得分:1)

这里的缓慢是循环中字符串连接的二次成本:

sb = String.Concat(sb,String.Join("\t",row),"\r\n");

由于这是一个非常明显的性能问题,我提交这个作为答案,因为它可能解决了你的问题。

如果您的应用很慢,请对其进行分析以查看 的速度。

不幸的是,ADO.NET在读取数据时确实非常重CPU。你无能为力。