我有一个存储过程,我在SQL2008服务器上开发,运行时间<1秒。在SQL2005的另一台服务器上,同一数据库上的相同sp需要大约1分钟。如果不了解数据库模式的细节,任何人都可以看到此SP中可能导致此性能差异的任何明显内容吗?这可能是CTE的使用吗?还有其他选择吗?
编辑 - 我现在已经注意到,如果我直接在SQL 2005上运行SQL,它运行~4secs但执行SP仍然需要一分钟?看起来像SP执行中的问题可能会发生什么?
CREATE PROCEDURE Workflow.GetTopTasks
-- Add the parameters for the stored procedure here
@ownerUserId int,
@topN int = 10
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SET ROWCOUNT @topN;
-- Insert statements for procedure here
WITH cteCalculatedDate (MilestoneDateId, CalculatedMilestoneDate)
AS
(
-- Anchor member definition
SELECT md.MilestoneDateId, md.SpecifiedDate
FROM Workflow.MilestoneDate md
WHERE md.RelativeMilestoneDateId IS NULL
UNION ALL
-- Recursive member definition
SELECT md.MilestoneDateId, CalculatedMilestoneDate + md.RelativeDays
FROM Workflow.MilestoneDate md
INNER JOIN cteCalculatedDate cte
on md.RelativeMilestoneDateId = cte.MilestoneDateId
)
-- Statement that executes the CTE
select
we.*
from Workflow.WorkflowElement we
left outer join cteCalculatedDate cte
on cte.MilestoneDateId = we.DueDateId
inner join Workflow.WorkflowInstance wi
on wi.WorkflowInstanceId = we.WorkflowInstanceId
left outer join Workflow.SchemeWorkflow sw
on sw.WorkflowInstanceId = wi.WorkflowInstanceId
left outer join Workflow.Scheme s
on s.SchemeId = sw.SchemeId
inner join Workflow.WorkflowDefinition wd
on wd.WorkflowDefinitionId = wi.WorkflowDefinitionId
where
we.OwnerId = @ownerUserId -- for given owner
and we.CompletedDate is null -- is not completed
and we.ElementTypeId <= 4 -- is Action, Data, Decision or Document (Not End, Start or KeyDate)
and cte.CalculatedMilestoneDate is not null -- has a duedate
UNION
select
we.*
from Workflow.WorkflowElement we
left outer join cteCalculatedDate cte
on cte.MilestoneDateId = we.DueDateId
inner join Workflow.WorkflowInstance wi
on wi.WorkflowInstanceId = we.WorkflowInstanceId
left outer join Workflow.SchemeWorkflow sw
on sw.WorkflowInstanceId = wi.WorkflowInstanceId
left outer join Workflow.Scheme s
on s.SchemeId = sw.SchemeId
inner join Workflow.WorkflowDefinition wd
on wd.WorkflowDefinitionId = wi.WorkflowDefinitionId
where
we.OwnerId = @ownerUserId -- for given owner
and we.CompletedDate is null -- is not completed
and we.ElementTypeId <= 4 -- is Action, Data, Decision or Document (Not End, Start or KeyDate)
and cte.CalculatedMilestoneDate is null -- does NOT have a duedate
SET ROWCOUNT 0
END
答案 0 :(得分:4)
编辑 - 我现在已经注意到了,如果我 直接在SQL 2005上运行SQL 运行~4secs但执行SP 还需要一分钟?
错误的参数嗅探:
http://elegantcode.com/2008/05/17/sql-parameter-sniffing-and-what-to-do-about-it/
SQL poor stored procedure execution plan performance - parameter sniffing
参数嗅探在2005年很糟糕,但在2008年更好。
答案 1 :(得分:3)
你的联合选择CalculatedMilestoneDate等于NULL 和不等于Null。
这是多余的,只需从where子句中删除CalculatedMilestoneDate上的条件即可删除整个UNION。
除此之外,您应该验证两个数据库是否都定义了相同的索引。
-- Statement that executes the CTE
select
we.*
from Workflow.WorkflowElement we
left outer join cteCalculatedDate cte
on cte.MilestoneDateId = we.DueDateId
inner join Workflow.WorkflowInstance wi
on wi.WorkflowInstanceId = we.WorkflowInstanceId
left outer join Workflow.SchemeWorkflow sw
on sw.WorkflowInstanceId = wi.WorkflowInstanceId
left outer join Workflow.Scheme s
on s.SchemeId = sw.SchemeId
inner join Workflow.WorkflowDefinition wd
on wd.WorkflowDefinitionId = wi.WorkflowDefinitionId
where
we.OwnerId = @ownerUserId -- for given owner
and we.CompletedDate is null -- is not completed
and we.ElementTypeId <= 4 -- is Action, Data, Decision or Document (Not End, Start or KeyDate)
答案 2 :(得分:0)
如果模式匹配,那么您可能缺少sql server 2005实例中的重要索引。尝试运行sql server tuning顾问并应用其索引建议。