我在我的数据库这个存储过程:SELECT不同的输入对查询速度有很大的影响?
ALTER PROCEDURE [dbo].[sp_FTSearchLocation]
@SearchFor nvarchar(200) = null
,@StartRow int
,@EndRow int
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM (
SELECT TOP (@EndRow)
*, ROW_NUMBER() OVER (ORDER BY Recommendations DESC, CompanyName) AS num
FROM
dbo.cachedSearchTable
WHERE
(
(@SearchFor IS NULL)
OR (CompanyName like '%' + @SearchFor + '%')
OR (Handle like '%' + @SearchFor + '%')
OR (Activity like '%' + @SearchFor + '%')
)
) As a
WHERE num > @StartRow
OPTION (RECOMPILE)
END
dbo.cachedSearchTable
与列Recommendations DESC, CompanyName
聚簇索引。没有其他索引。我认为使用*
是安全的,因为表cachedSearchTable
被构建为仅具有与该查询相关的列。
对于某些搜索字符串,此过程运行速度非常快。例如,搜索accountants
的回报不到一秒钟。但是,其他人运行速度非常缓慢:当@SearchFor
设置为soup
时,大约需要6秒钟才能返回。
每个这些执行计划看起来是一样的:
对于Accountants
:
ClusteredIndexScan (85%) ->
Segment (15%) ->
ComputeScalar (0%) ->
SequenceProject (0%) ->
Top (0%) ->
Filter (0%) ->
Select (0%).
对于Soup
:
ClusteredIndexScan (95%) ->
Parallelism (Gather Streams) (5%) ->
Segment (0%) ->
ComputeScalar (0%) ->
SequenceProject (0%) ->
Top (0%) ->
Filter (0%) ->
Select (0%).
然而,对于accountants
,该ClusteredIndexScan的估计运营商成本为0.57,而soup
则成本为25.34。
我试着在表格上放置3个非聚集索引 - 每个搜索列一个 - 但这没有帮助。
我的数据库中有很多会计师(〜4000),很少有他们名字中的“汤”(〜50)。一般来说,当有大量可能的结果可供选择时,查询运行得最快,而当返回的结果非常少时,查询运行速度最慢。
如何加快此查询?减慢写入速度并不重要,但应用更多索引似乎没有帮助。你能提出什么建议吗?
您是否尝试更新统计信息?我使用类似的问题就像你的问题后,我把大量的记录表table.I认为统计碎片不会更新不正确,可能是SQL的原因得到错误的执行计划。只是一个猜测 – 2012-02-15 16:44:00
它被称为参数嗅探 - 本质上,SQL Server根据您传递的第一个参数编译计划,但它可能会根据不同的参数做出不同的决定。你是否比较了好的和坏的执行的执行计划?请参阅http:// stackoverflow。com/questions/1007397/sql-poor-stored-procedure-execution-plan-performance-parameter-sniffing and also get our free Plan Explorer tool which highlight these issues more better http://sqlsentry.net/plan-explorer/ sql-server-query-view.asp – 2012-02-15 16:44:28
@AaronBertrand谢谢,我会得到你的软件,它看起来很有用。实际的存储过程有很多额外的参数(全部可能为空),所以它有'选项(重新编译)'集合,我认为这意味着每次重新编译一个计划。我编辑了我的问题来表明这一点。 – Oliver 2012-02-15 16:54:32