为什么SQLCLR proc会比同一个代码客户端运行得慢

时间:2009-05-19 15:19:55

标签: sql-server-2005 sqlclr

我正在编写一个存储过程,完成后将用于逐列扫描临时表中的伪造数据。

练习中的第一步只是扫描表格 - 这就是下面的代码所做的。问题是这段代码在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(*)聚合 - 这不是本练习的目的。

2 个答案:

答案 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秒)

当然,现在必须将程序集部署为外部而不是安全 - 这会带来更多的挫败感。