【发布时间】:2012-12-10 20:03:50
【问题描述】:
我有一个应用程序,我必须从数据库中获取大量数据。 由于它未能获取所有这些行(接近 2,000,000 行...),我将其中断,并且每次运行 sql 查询时,每次仅获取 200,000 行。
我使用向其中输入所有数据的 DataTable(意思是 - 所有 2,000,000 行都应该在那里)。
前几次运行都很好。然后它会因 OutOfMemoryException 而失败。
我的代码如下:
private static void RunQueryAndAddToDT(string sql, string lastRowID, SqlConnection conn, DataTable dt, int prevRowCount)
{
if (string.IsNullOrEmpty(sql))
{
sql = generateSqlQuery(lastRowID);
}
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
using (IDbCommand cmd2 = conn.CreateCommand())
{
cmd2.CommandType = CommandType.Text;
cmd2.CommandText = sql;
cmd2.CommandTimeout = 0;
using (IDataReader reader = cmd2.ExecuteReader())
{
while (reader.Read())
{
DataRow row = dt.NewRow();
row["RowID"] = reader["RowID"].ToString();
row["MyCol"] = reader["MyCol"].ToString();
... //In one of these rows it returns the exception.
dt.Rows.Add(row);
}
}
}
if (conn != null)
{
conn.Close();
}
if (dt.Rows.Count > prevRowCount)
{
lastRowID = dt.Rows[dt.Rows.Count - 1]["RowID"].ToString();
sql = string.Empty;
RunQueryAndAddToDT(sql, lastRowID, conn, dt, dt.Rows.Count);
}
}
在我看来,读者好像一直在收集行,这就是它只在第三轮或第二轮抛出异常的原因。
不应该像使用那样清理内存吗? 什么可以解决我的问题?
注意:我应该解释一下 - 我别无选择,只能将所有这些行放到数据表中,因为我稍后会对它们进行一些操作,并且行的顺序很重要,我不能拆分它是因为有时我必须将某些行的数据设置为一行等等,所以我不能放弃它。
谢谢。
【问题讨论】:
-
只是一个注释,如果数据大小增加一倍或三倍怎么办。必须有一个方法才能只拉回一些数据,否则你以后可能会遇到很多麻烦。
-
加载 2M 行是非常少见的——大多数时候的想法是尽量减少加载的数据量。如果你需要 2M 行,DataTable 可能不是最好的模型(DataTable 有开销)。我个人会将其加载到 POCO 模型中。
标签: c# sql exception datareader using-statement