我正在使用SqlDataReader从DBMS中检索一些"SELECT"查询。到目前为止,我使用 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),"rn");
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),"rn");
if (sb.Length > 100000)
{
File.AppendAllText(currentout,sb);
sb = "";
}
}
File.AppendAllText(currentout,sb);
}
reader.Close();
reader.Dispose();
cmd.Dispose();
conn.Close();
"Td"组件是用于.NET的Teradata DBMS接口(但它们的行为就像"SQL"组件一样)。
这里慢的是循环中字符串连接的二次成本:
sb = String.Concat(sb,String.Join("t",row),"rn");
由于这是一个如此明显的性能问题,因此我将其作为答案提交,因为它可能会解决您的问题。
如果您的应用运行缓慢,请对其进行分析以查看运行缓慢的内容。
不幸的是,读取数据时 ADO.NET 确实占用了大量 CPU。你对此无能为力。