繁体   English   中英

使用参数的sql语句速度很慢,如果没有参数,则速度很快

[英]Sql statement using parameters is slow, fast without them

我在参数化sql语句的性能方面遇到了一些麻烦。 我正在使用的表有〜150,000条记录,每条记录都有〜30列。

该语句在3.5秒内执行。

    Dim selectstring As String
    selectstring = "SELECT * FROM LineInfo WHERE jobNum=@jobnum and revision_number=@revnum AND lineNum=@linenum;"
    Dim selectCommand As New SqlClient.SqlCommand(selectstring, Singleton.DbConnection)
    selectCommand.Parameters.Add("@jobnum", "testing1")
    selectCommand.Parameters.Add("@revnum", "0")
    selectCommand.Parameters.Add("@linenum", 13)

    Dim da As New SqlClient.SqlDataAdapter(selectCommand)
    Dim ds As New DataSet

    Try
        da.Fill(ds)
        MsgBox("Done.")
        ds.Dispose()
    Catch ex As System.Exception
        MsgBox(ex.Message)
    End Try

    da.Dispose()

该select语句在.0015秒内执行。

    Dim selectstring As String
    selectstring = "SELECT * FROM LineInfo WHERE jobNum='testing1' and revision_number=0 AND lineNum=13;"

    Dim selectCommand As New SqlClient.SqlCommand(selectstring, Singleton.DbConnection)
    Dim ds As New DataTable
    Dim a As New SqlClient.SqlDataAdapter(selectCommand)

    Try
        a.Fill(ds)
        MsgBox("Done.")
        ds.Dispose()
    Catch ex As System.Exception
        MsgBox(ex.Message)
    End Try

    a.Dispose()

我已经在论坛上阅读了一些有关参数嗅探的内容,但这似乎与存储过程有关。 我不确定从这里到哪里去,所以我想我会在堆栈溢出时尝试所有这些。 有谁知道是什么引起了这个问题?

运行SQL事件探查器,并检查击中数据库的实际SQL。 接受这两个查询,并在启用了“显示执行计划”的Query Analyzer / SQL Server Management Studio中运行它们,并查找花费时间。

如果服务器上的性能相同,请再次检查.NET代码。 有什么理由为什么要在上面的示例中使用DataSet而在下面的示例中使用DataTable?

我希望您的查询时间更快是因为SQL Server以前已经缓存了您的确切查询。 尝试更改这些值,然后查看它是否仍然可以快速运行。

我会专门看

selectCommand.Parameters.Add("@jobnum", "testing1")

在进行查找之前,我曾经历过将整个索引转换为unicode的经历。 这可能是罪魁祸首。 在这种情况下,您要创建一个参数并将其设置为键入ansi字符串或类似的字符串。

不能肯定地说(并不是真的引起了SQL引擎的所有复杂性),但是首先让我惊讶的是对数字列使用字符串参数:

selectCommand.Parameters.Add("@revnum", "0")

revision_number=0

我怀疑在第二个示例中,如果您使用字符串而不是数字值,那么它也会变慢...尝试一下,看看会发生什么。

我必须将参数语句更改为:

   selectCommand.Parameters.Add("@jobnum", SqlDbType.Char).Value = "testing1"
   selectCommand.Parameters.Add("@revnum", SqlDbType.Int).Value = 0
   selectCommand.Parameters.Add("@linenum", SqlDbType.Int).Value = 13

仅更改@revnum参数是不够的,我不得不全部更改。 无论如何,它都在起作用,我现在知道如何处理它。

谢谢。

您是否能够始终如一地重现每个版本的执行时间? 是否有可能先运行参数化版本,然后在运行动态SQL版本时查询已被缓存?

我不知道您的.net驱动程序是否具有相似的功能,但是JDBC驱动程序具有选项“ sendStringParametersAsUnicode”,请参阅http://msdn.microsoft.com/de-de/library/ms378988.aspx

我怀疑这是否是答案,因为我不太了解VB,但是我看到在第一个代码段中,将revnum设置为“ 0”,而将linenum设置为13(无引号)。

我不知道VB数据的键入方式是否足够自信,但是在将revnum作为字符串并且必须在SQL查询过程中将其转换为整数的情况下,会不会出现一些怪异的行为?

我相信参数嗅探也适用于此,因为SQL Server像存储过程一样缓存SQL语句的执行计划。 您可以尝试清除语句高速缓存,然后使用相同的参数在运行速度最快的地方重新运行该语句,以查看其是否加速。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM