是否有 faster/smarter 方式来填充数据表而不是 DataTable.Load(DataReader)? C#
Is there a faster/smarter way, to fill a datatable than DataTable.Load(DataReader)? C#
我正在做一些研究,以更好地理解 SQL 和使用 DataTables。
所以我试图从 MS SQL 数据库中读取数据并将其加载到数据网格视图中。
我创建了一个 SQL 函数,我从我的工具中调用它并将结果加载到数据表中。
如果我在 SSMS 中执行此函数,加载结果需要 11-12 秒(将近 150 万条条目),但如果我使用我编写的工具执行此函数,则需要 30 多秒(仅做 DataTable.Load(SqlDataReader))
到目前为止我所做的是:
private DataTable GetDataFromDB(string userId, string docId, DateTimeOffset date)
{
string cmd = String.Format("select * from dbo.GetData(@userId, @docId, @dueDate);");
using (SqlConnection conn = new SqlConnection(connectionString))
{
if (conn.State != ConnectionState.Open)
conn.Open();
SqlCommand command = new SqlCommand(cmd, conn);
if (String.IsNullOrEmpty(userId))
command.Parameters.AddWithValue("@userId", DBNull.Value);
else
command.Parameters.AddWithValue("@userId", userId);
if (String.IsNullOrEmpty(docId))
command.Parameters.AddWithValue("@docId", DBNull.Value);
else
command.Parameters.AddWithValue("@docId", docId);
command.Parameters.AddWithValue("@dueDate", dueDate);
SqlDataReader reader = command.ExecuteReader();
stopWatch.Reset();
stopWatch.Start();
table.BeginLoadData();
table.Load(reader, LoadOption.Upsert);
table.EndLoadData();
stopWatch.Stop();
reader.Close();
reader.Dispose();
conn.Close();
}
return table;
}
我已经做了一些 google 研究,这是我能想到的最好的。到目前为止它运行良好,但我很好奇是否有可能更快地获得结果。有任何想法吗?
我的内存也有问题。一旦我开始通话,该工具就会分配多达 900MB 的 RAM,直到它拥有所有条目。我已经设法在每次调用上面的函数时释放内存,但我认为,900MB 已经很多了,另一个问题是,它不会释放所需的所有 RAM。例如:当我启动该工具时,它需要大约 7MB 的 RAM,如果我第一次调用上面的方法,它将需要 900MB。如果我下次调用它,它会释放大部分内存,但仍需要 930MB。第三次960MB等等。因此,每次调用它都会分配更多内存,如果经常调用此方法,这将导致 "System out of memory"-Exception。
非常感谢!
性能会因加载的数据内容和数据量而异。
下面link会给你解决方案和性能报告。用你的方法尝试这样的事情并比较性能。
希望对您有所帮助。
对我来说,使用 DataTable.Load(SqlDataReader) 是最快的方法
DataTable dt = new DataTable();
using (var con = new SqlConnection { ConnectionString = "ConnectionString" })
{
using (var command = new SqlCommand { Connection = con })
{
con.Open();
command.CommandText = @"SELECT statement.....";
command.Parameters.AddWithValue("@param", "Param");
//load the into DataTable
dt.Load(command.ExecuteReader(), LoadOption.Upsert);
}// this will dispose command
}// this will dispose and close connection
我正在做一些研究,以更好地理解 SQL 和使用 DataTables。 所以我试图从 MS SQL 数据库中读取数据并将其加载到数据网格视图中。
我创建了一个 SQL 函数,我从我的工具中调用它并将结果加载到数据表中。 如果我在 SSMS 中执行此函数,加载结果需要 11-12 秒(将近 150 万条条目),但如果我使用我编写的工具执行此函数,则需要 30 多秒(仅做 DataTable.Load(SqlDataReader))
到目前为止我所做的是:
private DataTable GetDataFromDB(string userId, string docId, DateTimeOffset date)
{
string cmd = String.Format("select * from dbo.GetData(@userId, @docId, @dueDate);");
using (SqlConnection conn = new SqlConnection(connectionString))
{
if (conn.State != ConnectionState.Open)
conn.Open();
SqlCommand command = new SqlCommand(cmd, conn);
if (String.IsNullOrEmpty(userId))
command.Parameters.AddWithValue("@userId", DBNull.Value);
else
command.Parameters.AddWithValue("@userId", userId);
if (String.IsNullOrEmpty(docId))
command.Parameters.AddWithValue("@docId", DBNull.Value);
else
command.Parameters.AddWithValue("@docId", docId);
command.Parameters.AddWithValue("@dueDate", dueDate);
SqlDataReader reader = command.ExecuteReader();
stopWatch.Reset();
stopWatch.Start();
table.BeginLoadData();
table.Load(reader, LoadOption.Upsert);
table.EndLoadData();
stopWatch.Stop();
reader.Close();
reader.Dispose();
conn.Close();
}
return table;
}
我已经做了一些 google 研究,这是我能想到的最好的。到目前为止它运行良好,但我很好奇是否有可能更快地获得结果。有任何想法吗? 我的内存也有问题。一旦我开始通话,该工具就会分配多达 900MB 的 RAM,直到它拥有所有条目。我已经设法在每次调用上面的函数时释放内存,但我认为,900MB 已经很多了,另一个问题是,它不会释放所需的所有 RAM。例如:当我启动该工具时,它需要大约 7MB 的 RAM,如果我第一次调用上面的方法,它将需要 900MB。如果我下次调用它,它会释放大部分内存,但仍需要 930MB。第三次960MB等等。因此,每次调用它都会分配更多内存,如果经常调用此方法,这将导致 "System out of memory"-Exception。
非常感谢!
性能会因加载的数据内容和数据量而异。 下面link会给你解决方案和性能报告。用你的方法尝试这样的事情并比较性能。
希望对您有所帮助。
对我来说,使用 DataTable.Load(SqlDataReader) 是最快的方法
DataTable dt = new DataTable();
using (var con = new SqlConnection { ConnectionString = "ConnectionString" })
{
using (var command = new SqlCommand { Connection = con })
{
con.Open();
command.CommandText = @"SELECT statement.....";
command.Parameters.AddWithValue("@param", "Param");
//load the into DataTable
dt.Load(command.ExecuteReader(), LoadOption.Upsert);
}// this will dispose command
}// this will dispose and close connection