【问题标题】:SQL Server sp_executesql timeoutSQL Server sp_executesql 超时
【发布时间】:2015-10-12 11:59:00
【问题描述】:

以下查询(没有详细信息)以超时结束。所有列都有 nvarchar 类型。所以这与this 无关。查询在没有 sp_executesql 的情况下也能完美运行。

exec sp_executesql N'declare @exp nvarchar(max) = ''%'' + @name + ''%''

select u.Id
from [local_db]..Users u
    join [linked_server].[remote_db].dbo.Players p on p.PlayerId = u.PlayerId
    join [linked_server].[remote_db].dbo.PlayerStats ps on ps.PlayerId = u.PlayerId
where @exp is null or u.Nickname like @exp or u.Name like @exp or p.Nickname like @exp
order by ps.Wins desc
offset @skip rows fetch next @take rows only',N'@skip int,@take int,@name nvarchar(8)',@skip=0,@take=24,@name=N'Foo'

我发现了一些有趣的细节。如果我删除or p.Nickname like @exp,它会起作用。当我删除or u.Nickname like @exp or u.Name like @exp 时,也会发生同样的情况。但这只是一个想法。


更新

下一个查询工作正常!

exec sp_executesql N'
declare @skip int = 0, @take int = 24, @name nvarchar(8) = N''Foo''
declare @exp nvarchar(max) = ''%'' + @name + ''%''

select u.Id
from [local_db]..Users u
    join [linked_server].[remote_db].dbo.Players p on p.PlayerId = u.PlayerId
    join [linked_server].[remote_db].dbo.PlayerStats ps on ps.PlayerId = u.PlayerId
where @exp is null or u.Nickname like @exp or u.Name like @exp or p.Nickname like @exp
order by ps.Wins desc
offset @skip rows fetch next @take rows only'

【问题讨论】:

  • 性能问题是因为您通过使用前导通配符将整个查询呈现为 nonSARGable。当您搜索较少的列时它“工作”的原因是因为它能够足够快地扫描其他列以避免超时。
  • 但没有 sp_executesql 也能完美运行。
  • 我不确定我会说得很完美,因为它无疑很慢。从您发布的内容来看,我看不出有任何理由使用动态 sql。此查询是否还有更多需要您使用动态 sql 的内容?
  • 这个查询是由实体框架创建的,当调用Database.SqlQuery方法时。
  • 呃,我从未使用过 EF,但从我所看到的一切来看,它创建了一些最糟糕的 sql。有没有办法让它不使用前导通配符,或者这是搜索正常工作的要求?遗憾的是,您几乎无法做任何事情来加快速度,因为这些列上的任何索引都无法使用。

标签: sql-server entity-framework timeout sp-executesql


【解决方案1】:

带有 sp_executesql 和不带它的查询有不同的执行计划(为什么???)。如果 sp_executesql 分析器建议我在包含列(Id、Name、Nickname)的用户(PlayerId)上创建索引。它就像一个魅力!如果您遇到此问题,请尝试分析您的查询。

【讨论】:

  • 很高兴这对您有用,但您需要对建议的索引持保留态度。有时你很幸运,他们实际上提供了帮助。很多时候,它们使查询变慢。我不会完全忽视这些建议,但需要对它们进行分析和测试,看看它们是否真的有帮助。
  • 当然。但是经过一整天的搜索解决方案和理解问题,这是一个简单的决定:)
【解决方案2】:

我遇到了同样的问题。一个使用sp_executesql 运行缓慢(大约一分钟)的查询,没有它也很好(即时结果)。 两个执行计划不同。我所做的只是重新计算我的主表的统计数据,它就起作用了。

我不知道为什么它会变得不同。在我重新计算之前,这些统计数据似乎没有损坏或不平衡。

【讨论】:

  • @NilsGudat,我认为“我所做的只是重新计算我的主表的统计信息”是一个答案。这是我以前用来解决性能缓慢的查询的方法!措辞有点模棱两可,但我很确定这不是试图问另一个问题=)
  • 这是一个答案。
猜你喜欢
  • 2023-03-25
  • 2011-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-04
  • 2012-07-06
  • 2012-07-28
相关资源
最近更新 更多