[英]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.