2012-11-22 67 views
1

我已创建如果创建它需要12-13秒来运行此确切查询存储的过程,其与aprox的2秒前100执行查询。查询比存储过程慢得多?

为什么会是这样?

  • 元素表计数= 2309015(具有用户标识指定= 326969)
  • 匹配表计数= 1290(具有用户标识指定= 498)
  • 网站表计数= 71(与用户ID指定= 9)

代码

with search (elementid, siteid, title, description, site, link, addeddate) 
as 
(
    select top(@top) 
     elementid, 
     elements.siteid, title, elements.description, 
     site = 
      case sites.description 
       when '' then sites.name 
       when null then sites.name 
       else sites.name + ' (' + sites.description + ')' 
      end, 
     elements.link, 
     elements.addeddate 
    from elements 
     left join sites on elements.siteid = sites.siteid 
    where title like @search and sites.userid = @userid 
    order by addeddate desc 
) 
select search.*, isnull(matches.elementid,0) as ismatch 
from search 
    left join matches on matches.elementid = search.elementid 
+0

你已经看过了查询执行计划的问题? –

+0

“我已创建如果创建它需要12-13秒来运行此确切查询存储的过程,其与aprox的2秒前100执行查询”。它如下,该存储过程这么多比查询慢。 –

+0

@HamletHakobyan我不明白,sp很慢是的...(现在查看执行计划) –

回答

0

没有代码,我只能猜测。在编写示例查询时,首先有一个常量where子句和第二个高速缓存。存储过程没有机会根据where子句中的常量来缓存或优化查询计划。

+0

我不明白为什么会有差异。运行存储过程时,我运行它像这样:exec web_storedprocedure 1,100,'%searchphrase%'。这是一个缓慢的存储过程,它没有缓存任何东西...我会理解它,如果查询是一个很慢.... –

0

我可以建议两种方式来尝试

首先一个,写你的SP这样的:

create procedure sp_search 
(
    @top int, 
    @search nvarchar(max), 
    @userid int 
) 
as 
begin 
    declare @p_top int, @p_search nvarchar(max), @p_userid int 

    select @p_top = @top, @p_search = @search, @p_userid = @userid 

    with search (elementid, siteid, title, description, site, link, addeddate) 
    as 
    (
     select top(@p_top) 
      elementid, 
      elements.siteid, title, elements.description, 
      site = 
      case sites.description 
       when '' then sites.name 
       when null then sites.name 
       else sites.name + ' (' + sites.description + ')' 
      end, 
      elements.link, 
      elements.addeddate 
     from elements 
      left join sites on elements.siteid = sites.siteid 
     where title like @p_search and sites.userid = @p_userid 
     order by addeddate desc 
    ) 
    select search.*, isnull(matches.elementid,0) as ismatch 
    from search 
     left join matches on matches.elementid = search.elementid 
end 

第二个,使用内联表函数

create function sf_search 
(
    @top int, 
    @search nvarchar(max), 
    @userid int 
) 
returns table 
as 
return 
(
    with search (elementid, siteid, title, description, site, link, addeddate) 
    as 
    (
     select top(@top) 
      elementid, 
      elements.siteid, title, elements.description, 
      site = 
      case sites.description 
       when '' then sites.name 
       when null then sites.name 
       else sites.name + ' (' + sites.description + ')' 
      end, 
      elements.link, 
      elements.addeddate 
     from elements 
      left join sites on elements.siteid = sites.siteid 
     where title like @search and sites.userid = @userid 
     order by addeddate desc 
    ) 
    select search.*, isnull(matches.elementid,0) as ismatch 
    from search 
     left join matches on matches.elementid = search.elementid 
) 
+0

我不认为参数嗅探一般建议?我读过这样做的许多缺点(与你发布的sp有关) – Ric

1

当你创建SP它被编译和存储,并且当SP具有参数时,通过该参数筛选结果,优化程序不知道您将执行哪个值,然后他将其视为33%选择,并由此创建计划。在执行查询时,会提供这些值,优化程序将根据此值创建执行计划。我确定,这些计划是不同的。

0

有一个类似的问题here

是在存储过程声明SET ANSI_NULLS OFF