- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一些工作的 C# 代码使用 SqlConnection 创建临时表(例如,#Foo),调用存储过程来填充这些临时表并将结果返回到 C# 客户端,使用 c# 对这些结果执行复杂的计算,并使用计算结果更新之前创建的其中一个临时表。
由于在整个过程中使用临时表,我们必须只有一个 SqlConnection。
我发现了用计算结果更新临时表的性能瓶颈。此代码已对更新进行批处理,以防止 C# 客户端内存不足。每批计算数据都通过 SqlCommand.ExecuteNonQuery 发送到存储过程,存储过程依次更新临时表。代码大部分时间都花在调用 ExecuteNonQuery 上。
因此,我将其更改为 BeginExecuteNonQuery,以及等待线程和调用 EndExecuteNonQuery 的代码。这将性能提高了大约三分之一,但我担心使用相同的 SqlConnection 对 SqlCommand.BeginExecuteNonQuery 进行多个并发调用。
这样可以吗,还是会遇到线程问题?
抱歉,解释得太长了。
MSDN 文档状态:
The BeginExecuteNonQuery method returns immediately, but until the code executes the corresponding EndExecuteNonQuery method call, it must not execute any other calls that start a synchronous or asynchronous execution against the same SqlCommand object.
这似乎意味着不同的 SqlCommand 对象可以在第一个 SqlCommand 完成之前调用 BeginExecuteNonQuery。
下面是一些说明问题的代码:
private class SqlCommandData
{
public SqlCommand Command { get; set; }
public IAsyncResult AsyncResult { get; set; }
}
public static void TestMultipleConcurrentBeginExecuteNonQueryCalls(string baseConnectionString)
{
var connectionStringBuilder = new SqlConnectionStringBuilder(baseConnectionString)
{
MultipleActiveResultSets = true,
AsynchronousProcessing = true
};
using (var connection = new SqlConnection(connectionStringBuilder.ConnectionString))
{
connection.Open();
// ELIDED - code that uses connection to do various Sql work
SqlDataReader dataReader = null;
// in real code, this would be initialized from calls to SqlCommand.ExecuteReader, using same connection
var commandDatas = new List<SqlCommandData>();
var count = 0;
const int maxCountPerJob = 10000;
while (dataReader.Read())
{
count++;
// ELIDED - do some calculations on data, too complex to do in SQL stored proc
if (count >= maxCountPerJob)
{
count = 0;
var commandData = new SqlCommandData
{
Command = new SqlCommand {Connection = connection}
};
// ELIDED - other initialization of command - used to send the results of calculation back to DB
commandData.AsyncResult = commandData.Command.BeginExecuteNonQuery();
commandDatas.Add(commandData);
}
}
dataReader.Close();
WaitHandle.WaitAll(commandDatas.Select(c => c.AsyncResult.AsyncWaitHandle).ToArray());
foreach (var commandData in commandDatas)
{
commandData.Command.EndExecuteNonQuery(commandData.AsyncResult);
commandData.Command.Dispose();
}
// ELIDED - more code using same SqlConnection to do final work
connection.Close();
}
}
最佳答案
好吧,冒着收到大量反对票的极端风险,我不得不对此发表评论。首先,这是一个很好的问题,并且很好地解决了您提到的特定潜在问题。但是,您忽略了讨论您试图完成的这个“冗长”过程。
我的经历让我想到了一件事......
If the question your asking is hard to answer, change the question.
虽然我对您的具体问题知之甚少,但我认为这完全适用于您的困境。正如其他人所提到的......临时表很糟糕,为特定任务创建自己的表更糟糕,在 SQL 中更新大量数据非常昂贵。
Ask yourself "Can you avoid it all?"
人们常常选择在数据库中实现极其复杂的逻辑,因为他们相信 SQL 可以更快地完成它。实际上这是一个有缺陷的概念,数据库是存储/序列化设备,它们擅长存储、更新、定位和同步对数据的访问。他们没有很好的能力来处理复杂的操作。即使在 Microsoft(和其他公司)通过向其中注入(inject)完整的开发语言来对数据库进行 SCSS 之后,它也无法像编写良好的客户端那样发挥最佳性能(*取决于操作的复杂性,我怀疑您已经超过了)。
例如,您有一个大约 2GB 原始数据的数据库。您想要针对整个数据集生成复杂的报告或分析。好吧,简单地说,2gb 的内存很容易获得,使用字典或任何创建您需要的查找的方式将整个数据库(或您需要的部分)放入内存。取决于几个因素,整个事情的运行速度可能比 SQL 快几倍,可以很容易地进行单元测试,并且(恕我直言)比构建动态 SQL 的讨厌的存储过程更容易构建、调试和维护。即使有超过 2gb 的原始数据,也可以使用多种现有技术(B 树、ISAM 等)轻松创建客户端缓存。
我今天工作的产品在数据库中有 2.4tb 的数据,我们没有一个存储过程、连接语句,甚至没有一个不相等的 where 子句。
但是遗憾的是,我的建议可能与您的具体情况相关,也可能不相关,因为我不知道您的目标或限制。希望,如果没有别的,它会让你问自己:
"Am I asking the right question?"
关于c# - 使用相同的 SqlConnection 对 SqlCommand.BeginExecuteNonQuery 的多个并发调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6374911/
使用 DataSnap 2009,我似乎可以在客户端数据模块中使用远程数据库连接,使用 TDSProviderConection 和关联的 TSQLConnection。客户端很容易设置,我在表单上放
我很好奇为什么会这样。我今天早些时候遇到了这种情况 using (SqlConnection oConn = new SqlConnection(ConnectionString)) { us
我正在用 .Net Reflector 检查 SqlConnection . 我注意到有一个私有(private)构造函数,有趣的是它接受一个 SqlConnection 类作为参数。 我想知道的主要
我的问题:本周早些时候,我接到了加速我们程序中的任务的任务。我看着它,立即想到了在该任务中为函数使用并行 foreach 循环的想法。 我实现了它,通过了函数(包括所有子函数)并更改了 SqlConn
我想执行一个 SELECT 查询,然后执行一系列 UPDATE 查询(都在同一个表上); UPDATE 在重复调用的单独方法中实现。如果其中一个 UPDATE 查询失败,我希望它们全部失败/回滚 -
做什么 using (SqlConnection cn = new SqlConnection(connectionString)) 做吗? 最佳答案 new SqlConnection(connec
您好,我想问一下,创建 Singleton 以仅与 db 建立一个事件连接是否是个好主意。我想做的是: 1) 我有 wcf 服务 2)wcf服务从db获取数据 3)我想创建一个这样的单例,只有一个连接
尊敬的专业人士请帮我解决以下问题。在我的 .NET C# 应用程序中,有以下代码: SqlConnection connection = new SqlConnection( SQLCONNECTIO
我正在尝试更新一些代码。我有一个以此开头的 vb 文件... Imports System.Data.SqlClient Imports System.Data.Sql Imports System.
如果我打开一个到 SQL Server 的 SqlConnection,然后从多个后台线程发出多个查询,所有查询都使用该一个连接 - 这些查询是否会按顺序执行(不关心顺序) )? 具体来说,如果在一个
我们有一个使用 SQL Server 2008 R2 数据库的应用程序。在应用程序中,使用 SqlConnection 对象调用数据库。 此SqlConnection 对象在第一次访问时初始化一次,然
我正在尝试优化访问 SQL Server 2014 数据库的代码性能,并注意到连接池似乎并不像 ADO.NET 所宣传的那样工作。默认情况下,它应该被启用并且开箱即用(只要使用相同的连接字符串)。然而
我正在尝试使用 SqlConnection 和 SqlCommand 对象建立一个简单的 MS Access 数据库连接。 正如您在此处看到的,我是如何建立联系的: private SqlConnec
我有一个连接到数据库的 .NET 应用程序。 在我的 web.config 文件中有 用户名和密码已删除。 在我后面的代码中,我这样打开连接 protected void grabDat
SqlDataReader rdr = null; con = new SqlConnection(objUtilityDAL.ConnectionString); using (SqlCommand
public class db { public static string connectionString = WebConfigurationManager.Con
我需要你的帮助(眼睛)看看我哪里错了。 所以,我遇到了这个错误... 这是我正在做的... 一个登录用户,有一个角色,这个角色有或没有一些权限。 当他输入表单时,应用程序会根据他的角色检查用户权限。在
我不确定嵌套的 SqlConnections 是否可行,但我真的很想远离它。我现在在我的代码中遇到了一个范围问题,我正试图弄清楚如何解决它。 所以直到最近我还有一个全局 SqlConnection,它
我编写了以下代码(为简洁起见进行了删减): using (SqlConnection cn = new SqlConnection("Server=test;Database=test;User=te
我在另一台服务器上读取和写入数据到 Sql Server,因此我需要打开许多 SqlConnection,我在读取或写入完成后关闭它们,但有时我无法连接到服务器但是在我重新启动服务器后一切正常,我猜这
我是一名优秀的程序员,十分优秀!