.NET 中的预处理语句和内置连接池
Posted
技术标签:
【中文标题】.NET 中的预处理语句和内置连接池【英文标题】:Prepared statements and the built-in connection pool in .NET 【发布时间】:2011-06-13 20:04:57 【问题描述】:我有一个长时间运行的服务,有几个线程每秒调用以下方法数百次:
void TheMethod()
using (var c = new SqlConnection("..."))
c.Open();
var ret1 = PrepareAndExecuteStatement1(c, args1);
// some code
var ret2 = PrepareAndExecuteStatement2(c, args2);
// more code
PrepareAndExecuteStatement 是这样的:
void PrepareAndExecuteStatement*(SqlConnection c, args)
var cmd = new SqlCommand("query", c);
cmd.Parameters.Add("@param", type);
cmd.Prepare();
cmd.Parameters["@param"] = args;
return cmd.execute().read().etc();
我想重用准备好的语句,为每个连接准备一次并执行它们直到连接中断。我希望这会提高性能。
我可以使用内置的连接池来实现吗?理想情况下,每次建立新连接时,应自动准备所有语句,并且我需要访问这些语句的 SqlCommand 对象。
【问题讨论】:
我不明白你所说的“直到连接中断”是什么意思,以及在调用不同的准备好的语句之间究竟应该发生什么。 这完全取决于// some code
是什么!
如果有人重新启动 SQL Server,现有的连接将会中断。
在“一些代码”上,我处理语句的结果。
结果集的大小是多少?如果是较小的结果集,您可能希望使用 SqlDataReader。此外,默认情况下启用连接池。当您打开()或关闭()连接时,您只是从池中获取或返回池。
【参考方案1】:
建议采取稍微修改的方法。使用后立即关闭连接。您当然可以重复使用您的 SqlConnection。
//some code
正在完成的工作可能需要很长时间。您是否正在与其他网络资源、磁盘资源进行交互,或花费任何时间进行计算?您将来是否需要这样做?也许执行语句之间的时间间隔很长,以至于您想重新打开该连接。无论如何,连接应该延迟打开并提前关闭。
using (var c = new SqlConnection("..."))
c.Open();
PrepareAndExecuteStatement1(c, args);
c.Close();
// some code
c.Open();
PrepareAndExecuteStatement2(c, args);
c.Close();
// more code
Open Late, Close Early 是 John Papa 的 MSDN 杂志。
显然,我们现在在这里有一堆代码重复。考虑重构您的 Prepare...()
方法以执行打开和关闭操作。
也许你会考虑这样的事情:
using (var c = new SqlConnection("..."))
var cmd1 = PrepareAndCreateCommand(c, args);
// some code
var cmd2 = PrepareAndCreateCommand(c, args);
c.Open();
cmd1.ExecuteNonQuery();
cmd2.ExecuteNonQuery();
c.Close();
// more code
【讨论】:
我可能没听懂你的回答,但我认为这并不能解决我的问题。根据您的建议,我将继续准备语句(创建 SqlCommand 对象,设置查询字符串,定义每个参数的类型,调用 .Prepare(),设置变量并执行查询。我想简单地设置变量并执行TheMethod() 中之前准备好的语句。 @lzm:您实际上做得正确或按照建议进行。为每个创建一个新的 SqlCommand。 准备好的语句不应该准备一次并执行多次吗?以上是关于.NET 中的预处理语句和内置连接池的主要内容,如果未能解决你的问题,请参考以下文章