我使用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;组件)。
答案 0 :(得分:1)
这里的缓慢是循环中字符串连接的二次成本:
sb = String.Concat(sb,String.Join("\t",row),"\r\n");
由于这是一个非常明显的性能问题,我提交这个作为答案,因为它可能解决了你的问题。
如果您的应用很慢,请对其进行分析以查看 的速度。
不幸的是,ADO.NET在读取数据时确实非常重CPU。你无能为力。