此查询过去常常在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)
答案 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)