【发布时间】:2016-06-06 20:46:38
【问题描述】:
我的任务是创建一个应用程序来监视特定表上的任何“INSERT”事件。我打算使用 SqlDependency 在数据库和 C# 应用程序之间创建通知链接,但由于安全问题,我无法做到这一点。
因此,我将我的应用程序建模如下:
这很好,但事实证明,我正在查询的 SQL 表的大小相当大。该表有近 350 万行 55 列。加载到 C# DataTable 对象时,出现内存不足异常。
internal static DataTable ExecuteQuery(string query, Dictionary<string,string> parameters = null)
{
try
{
using (SqlConnection dbconn = new SqlConnection(SQLServer.Settings.ConnectionString))
using (SqlCommand cmd = new SqlCommand())
{
dbconn.Open(); // Open the connection
cmd.CommandText = query; // Set the query text
cmd.Connection = dbconn;
if (parameters != null)
{
foreach (var parameter in parameters) // Add filter parameters
cmd.Parameters.AddWithValue(parameter.Key, parameter.Value);
}
var dt = new DataTable();
using (SqlDataAdapter adpt = new SqlDataAdapter(cmd)){adpt.Fill(dt);} // MY ERROR OCCURS HERE!
dbconn.Close();
queryError = false;
return dt;
}
}
catch(Exception ex)
{
queryError = true;
EventLogger.WriteToLog("ExecuteQuery()", "Application", "Error: An error has occured while performing a database query.\r\nException: " + ex.Message);
return null;
}
}
运行上面的代码时,SqlDataAdapter.Fill(dt) 的行出现以下错误
引发了“System.OutOfMemoryException”类型的异常。
有没有一种方法可以重组我的应用程序或防止 DataTable 类出现这种令人难以置信的高内存消耗? SQL 服务器似乎有足够的能力从表中选择 *,但是当我用相同的数据填充 DataTable 时,我用掉了超过 6GB 的 RAM!为什么使用 DataTable 会有这么多开销?
这是我的flowchart的链接。
【问题讨论】:
-
您有什么理由不想在 SQL Server 中使用触发器来执行此操作?
-
每行的平均大小是多少?将其乘以行数。 DT 会产生多少“开销”(最多)? 无论如何, SQL server 流 这个例子中的结果集,所以它不需要一次全部实现。另一方面,DataTables 只存在于内存中并且是“一次性加载的”。
-
您也可以考虑 SQL 内置机制,如审计和版本控制,如果它们适用于您的 SQL 版本
标签: c# sql-server datatable out-of-memory