我正在编写一个存储过程,完成后将用于逐列扫描临时表中的伪造数据。
练习中的第一步只是扫描表格 - 这就是下面的代码所做的。问题是这段代码在5:45秒内运行---但是同样的代码运行作为控制台应用程序(当然更改了连接字符串)在大约44秒内运行。
using (SqlConnection sqlConnection = new SqlConnection("context connection=true"))
{
sqlConnection.Open();
string sqlText = string.Format("select * from {0}", source_table.Value);
int count = 0;
using (SqlCommand sqlCommand = new SqlCommand(sqlText, sqlConnection))
{
SqlDataReader reader = sqlCommand.ExecuteReader();
while (reader.Read())
count++;
SqlDataRecord record = new SqlDataRecord(new SqlMetaData("rowcount", SqlDbType.Int));
SqlContext.Pipe.SendResultsStart(record);
record.SetInt32(0, count);
SqlContext.Pipe.SendResultsRow(record);
SqlContext.Pipe.SendResultsEnd();
}
}
然而,相同的代码(当然是不同的连接字符串)在大约44秒内在控制台应用程序中运行(这更接近我在客户端期望的那样)
我在SP方面缺少什么,这会导致它运行得如此之慢。
请注意:我完全理解如果我想要一个行数,我应该使用count(*)聚合 - 这不是本练习的目的。
答案 0 :(得分:2)
您编写的代码类型非常容易受到SQL注入的影响。您可以使用RecordsAffected属性来查找阅读器中的行数,而不是像处理读者一样处理读者。
编辑:
在做了一些研究之后,您看到的差异是上下文连接和常规连接之间的设计差异。彼得·德贝塔(Peter Debetta)在博客中写道并写道:
“写入上下文连接使得它一次只获取一行,因此对于2000万个奇数行中的每一行,代码分别要求每一行。但是,使用非上下文连接,它一次请求8K行。“
http://sqlblog.com/blogs/peter_debetta/archive/2006/07/21/context-connection-is-slow.aspx
答案 1 :(得分:1)
好吧,似乎答案就在连接字符串中。
context connection=true
与
server=(local); database=foo; integrated security=true
对于一些古怪的原因,使用“外部”连接,SP的运行速度几乎与控制台应用程序一样快(但仍然没有那么快! - 55秒)
当然,现在必须将程序集部署为外部而不是安全 - 这会带来更多的挫败感。