我们遇到了一个合理的简单存储过程的性能问题,因此我们需要备份数据库并在简单的测试机器和生产环境的副本上进行恢复。机器和数据库的唯一区别是硬件,一个是带有8Gig RAM和4个处理器的VM,另一个是物理集群64Gig RAM和8个处理器。
我们在两台计算机上都有相同版本的SQL Server(2014 SP1),这两个数据库都是从同一备份恢复的。当我们运行时,一个需要不到一秒钟,另一个需要2分40秒,产生相同的2976行结果集。
所涉及的主表只有大约59K行。执行计划几乎相同,但是对于其中一个聚集索引扫描的输出
所以让我疯狂的是,在相同版本的SQL Server上,相同数据库如何/为什么会产生两个截然不同的实际行数(174822900 vs 58764),执行次数为2975次而4?
这是正在运行的代码
DBCC FREEPROCCACHE;
DECLARE @return_value int
EXEC @return_value = [dbo].[ngage_Tree_SelectClientData]
@ParentId = 0,
@FromDate = '2016-08-04 17:16:40.367',
@UserGroupId = '1|',
@MaxToReturn = 100000
SELECT 'Return Value' = @return_value;
这是存储过程iteself的代码:
CREATE PROC dbo.ngage_Tree_SelectClientData
@ParentId BIGINT
,@FromDate DATETIME2
,@UserGroupId VARCHAR(50)
,@MaxToReturn INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @parentHierarchyId HIERARCHYID = (SELECT HierarchyId
FROM Tree
WHERE Id = @ParentId);
SELECT DISTINCT TOP (@MaxToReturn)
t.Id, t.ParentId,
t.Title, t.Ordinal, t.HelpTopicId,
t.IsFolder, t.SmallIcon, t.LargeIcon,
t.CmsTemplateId, t.IsSystemFolder,
t.ContextMenu, t.DateModified,
CASE
WHEN n2.[HierarchyId] IS NULL
THEN 0
ELSE 1
END AS 'HasChildren',
t.ToolTip,
t.[HierarchyId].ToString() AS ParentIds, t.Depth
FROM
Tree t
INNER JOIN
TreeToUserGroups ttug ON ttug.TreeId = t.Id
AND ttug.ReadPermission = 1
AND ttug.UserGroupId IN (SELECT ResultList
FROM dbo.SplitCommaList(@UserGroupId, '|'))
LEFT OUTER JOIN
Tree n2 ON t.[HierarchyId] = n2.[HierarchyId].GetAncestor(1)
WHERE
t.IsDeleted = 0
AND t.IsArchived = 0
AND t.DateModified > @FromDate
AND (@ParentId = 0
OR t.[HierarchyId].IsDescendantOf(@parentHierarchyId) = 1)
AND t.Id NOT IN (SELECT Id
FROM Tree
WHERE (TreeObjectType = N'EcomProduct'
AND Title = N'(MISC) MISC')
OR (Title = N'Tag Groups'
AND TreeObjectType = N'TagRoot')
)
ORDER BY
t.DateModified ASC;
END;