SQL 2000到SQL 2005.查询现在慢很多

时间:2009-08-24 07:16:30

标签: sql sql-server sql-server-2005

此查询过去常常在SQL2000中占用3秒,现在需要大约70秒。两个数据库都给出相同的结果。 2005数据库未在兼容模式下运行。

目前我们正在重建查询以在SQL2005中运行..通过消除和理解逻辑的过程。

然而 - 任何人都可以看到我们错过的任何明显的东西。

和/或有没有可以提供帮助的工具?

我们一直在查看执行计划......和分析器。和索引调整向导。

Profiler指向要查询的大量记录以获得相同的结果。

我知道在没有数据的情况下进行调试这是一个非常难的问题......如果有任何明显的话,另一双眼睛总是好的!

干杯

戴夫

ALTER            PROCEDURE [dbo].[GetNodeList]
@ViewID int,
@UserID int = null
as

Select ProcessList.*, 
A.NDOC_DOC_ID, 
A.NDOC_Order,
A.OMNIBOOK_ID, 
A.Node_Order
from (
    (SELECT N.NOD_ID, 
    N.NOD_Name, 
    N.NOD_Procname, 
    N.NOD_Xpos, 
    N.NOD_Ypos, 
    N.NOD_Zpos,
    VN.VNOD_VIE_ID
    FROM Node N 
    INNER JOIN View_NODe VN 
    ON N.NOD_ID = VN.VNOD_NOD_ID
    Where VN.VNOD_VIE_ID = @ViewID) ProcessList
Left Join
 (
    SELECT N.NOD_ID, 
    N.NOD_Name, 
    N.NOD_Procname, 
    N.NOD_Xpos as NOD_Xpos, 
    N.NOD_Ypos as NOD_Ypos, 
    N.NOD_Zpos as NOD_Zpos, 
    VN.VNOD_VIE_ID, 
    ND.NDOC_DOC_ID as NDOC_DOC_ID, 
    ND.NDOC_Order as NDOC_Order,
    null as OMNIBOOK_ID, 
    null as Node_Order
    FROM Node N 
    INNER JOIN View_NODe VN 
    ON N.NOD_ID = VN.VNOD_NOD_ID
    LEFT JOIN NODe_DOCument ND 
    ON N.NOD_ID = ND.NDOC_NOD_ID
    WHERE VN.VNOD_VIE_ID=@ViewID
    and ND.NDOC_DOC_ID is not null

    and (@UserID is null 
        or exists (Select 1 
                from Document D 
                where Doc_ID = ND.NDOC_DOC_ID 
                and dbo.fn_UserCanSeeDoc(@UserID,D.Doc_ID)<>0
        )
    )

    UNION

    SELECT N.NOD_ID, 
    N.NOD_Name, 
    N.NOD_Procname, 
    N.NOD_Xpos, 
    N.NOD_Ypos, 
    N.NOD_Zpos, 
    VN.VNOD_VIE_ID, 
    null, 
    null,
    NOM.OMNIBOOK_ID, 
    NOM.Node_Order
    FROM Node N 
    INNER JOIN View_NODe VN 
    ON N.NOD_ID = VN.VNOD_NOD_ID
    LEFT JOIN NODe_OMNIBOOK NOM 
    ON N.NOD_ID = NOM.NODE_ID
    WHERE VN.VNOD_VIE_ID=@ViewID
    and NOM.OMNIBOOK_ID is not null
    and exists (select 1 from Omnibook_Doc where OmnibookID = NOM.OMNIBOOK_ID)
) A
--On ProcessList.NOD_ID = A.NOD_ID
ON ProcessList.NOD_Xpos = A.NOD_Xpos
And ProcessList.NOD_Ypos = A.NOD_Ypos
And ProcessList.NOD_Zpos = A.NOD_Zpos
And ProcessList.VNOD_VIE_ID = A.VNOD_VIE_ID
) 
ORDER BY 
ProcessList.NOD_Xpos,
ProcessList.NOD_Zpos,
ProcessList.NOD_Ypos,
Coalesce(A.NDOC_Order,A.Node_Order),
Coalesce(A.NDOC_DOC_ID,A.OMNIBOOK_ID)

4 个答案:

答案 0 :(得分:2)

我之前看到过这种情况,因为统计数据没有跟上数据。在这种情况下,SQL Server 2005可能会使用与SQL Server 2000不同的统计信息。尝试重建查询中使用的表的统计信息;所以对于每个表:

UPDATE STATISTICS <table> WITH FULLSCAN

是的,我会添加FULLSCAN,除非你足够了解你的数据,认为记录样本会给出足够好的结果。它会减慢创建统计数据的速度,但会使其更准确。

答案 1 :(得分:1)

您的统计信息是否可能无法获得?在2k5 dbase?那么dbase没有制定好计划所需的信息?与您的旧数据库相比,该数据库具有良好的统计数据并可以为数据选择更好的计划?

答案 2 :(得分:0)

可能是“参数嗅探”的问题,即SQL Server缓存针对首次执行所提供的参数优化的查询计划? Microsoft technet has more

答案 3 :(得分:0)

大学已经提出了一个解决方案......关于将函数fn_UserCanSeeDoc带回SQL。

下面显示的是旧的注释掉的功能代码,然后是它下面的新内联SQL。现在代码运行速度非常快(从1分钟到大约一秒钟)

查看旧的SQL我很惊讶SQL2000运行它的工作有多好!

干杯

--and dbo.fn_UserCanSeeDoc(@UserID,D.Doc_ID)<>0

-- if exists(Select 1 from Omnibook where Omnibook_ID = @DocID) 
--      Begin
--          Set @ReturnVal =  1
--      End 
--  
--  else
--      Begin
--          if exists(
--              Select 1
--              from UserSecurityModule USM
--              Inner join DocSecurity DS
--              On USM.SecurityModuleID = DS.SecurityModuleID
--              where USM.UserID = @UserID
--              and DS.DocID = @DocID
--          )
--          
--              Set @ReturnVal =  1
--          
--          else
--                  
--              Set @ReturnVal = 0
--      End

AND D.Doc_ID IN (select DS.DocID from UserSecurityModule USM
                Inner join DocSecurity DS
                On USM.SecurityModuleID = DS.SecurityModuleID
                where USM.UserID = @UserID)