过时的数据库统计信息会降低 SharePoint Server 性能

关于数据库统计信息

查询优化的统计信息包含有关表或索引视图的一个或多个列中的值的分布的统计信息的对象。 查询优化器使用这些统计信息来估计查询结果中的基数或行数。 通过这些基数估计,查询优化器可以创建高质量的查询计划。

例如,查询优化器可以通过使用基数估计来选择索引 seek 运算符而不是占用大量资源的索引扫描运算符来提高查询性能。 否则,过期的统计信息可能会通过使用低效查询计划来降低查询性能。

大型企业 SharePoint 部署必须具有数据库维护计划,才能更新驻留在 Microsoft SQL Server 中的内容数据库上的数据库统计信息。 客户不应仅依赖基于 SharePoint 的数据库维护作业来执行这些任务。 有关详细信息,请参阅 SharePoint Server 服务器场中 SQL Server 的最佳实践

本文

数据库统计过期时,SharePoint Server 安装可能会遇到以下一种或多种症状:

  • 打开网站页面时,加载时间较慢并降低可能生成 HTTP 500 错误的性能

  • 较慢的性能,可生成错误消息,如以下示例所示:

    Service unavailable  
    Unknown SQL Exception 53  
    Server Error in '/' Application Runtime Error
    
  • 执行搜索爬网会导致意外的 SQL Server 性能、数据库锁定和阻止

  • 长时间运行的计时器作业,如 "Microsoft SharePoint Foundation 使用率数据处理" 作业,这些作业在每次迭代过程中花费的时间会变得越来越长。

  • 无法打开 SharePoint 网站,并出现类似于以下内容的错误消息:

    Unexpected System.Web.HttpException: Request timed out   
    
  • 加载导航时的网站呈现超时,并显示以下错误消息:

    PortalSiteMapProvider was unable to fetch children for node   
    
  • 处理 SharePoint 查询时运行 SQL Server 的服务器上的 CPU 使用率高

原因

这些问题可能是由过时的数据库统计信息引起的。 SharePoint 每天运行一次计时器作业,以使用 proc_updatestatistics SQL 过程更新数据库统计信息。 但是,由于各种原因,此计时器作业可能尚未完成,或者可能不会持续更新所有表。 例如,如果从 SQL Server 与 SharePoint 计时器作业同时对内容数据库运行备份,则该作业不会继续。

在完成更新统计信息的 SharePoint 计时器作业后,可能会将以下事件写入 ULS 日志:

  • e9bf "在数据库中更新统计信息时发生错误"。 {0}
  • cm1y "更新数据库中的统计信息 {0} "
  • dbl2 "跳过数据库的统计信息更新 {0} ,因为其状态为 {1} "
  • cm1x "更新所有数据库中的统计信息 {0} "

如果不严密监视这些条件,且未采取更正措施,则数据库统计信息过期,并且最终会发生 SharePoint 性能问题。

分辨率

为了防止这些症状和潜在的服务中断,应实施 SQL Server 维护计划,以使用 FULLSCAN 选项来更新 SharePoint 内容数据库统计信息。 有关详细信息,请参阅索引统计信息

在实现 SQL Server 维护计划以更新 SharePoint 数据库上的统计信息时,不需要从 SharePoint 禁用该作业。 但是,由于这些维护任务从这两个位置执行类似的功能,因此如果数据库由 SQL 管理,则可以允许禁用 sharepoint 场中的 "SharePoint 使用的数据库具有过时的索引统计信息" Heath Analyzer 规则。 有关如何从 SharePoint Server 管理索引更新作业的详细信息,请参阅sharepoint 使用的数据库具有过时的索引统计信息(SharePoint 2013)

详细信息

从 SQL Server 日开始,使用 FULLSCAN 选项更新 SharePoint 内容数据库的统计信息是建议的最佳实践。 有关详细信息,请参阅Sharepoint server 服务器场中 SQL Server 的最佳实践sharepoint Foundation 2010 的数据库维护

但是,如果您的 SharePoint 服务器场当前由于过期统计而遇到性能问题,则可将以下信息用作缓解此问题的一次性缓解步骤。

若要显示特定数据库中的数据库统计信息,请运行以下查询:

-- Checking the DB Stats  
select a.id as 'ObjectID', isnull(a.name,'Heap') as 'IndexName', b.name as 'TableName',   
stats_date (id,indid) as stats_last_updated_time   
from sys.sysindexes as a   
inner join sys.objects as b   
on a.id = b.object_id   
where b.type = 'U'  

有关数据库统计信息评审的详细信息,请参阅DBCC SHOW_STATISTICS

若要更新使用 FULLSCAN 选项的单个数据库上的数据库统计信息,请运行以下查询:

-- Update DB Stats  
EXEC sp_MSforeachtable 'UPDATE STATISTICS ? WITH FULLSCAN'  

重要说明 "sp_MSforeachtable" 选项是 "按原样" 提供的未记录的过程,应仅用于缓解即时问题。 建议您不要将此过程用作常规维护计划的一部分。 相反,请参阅我们的更新统计信息(transact-sql)文档,了解如何使用 FULLSCAN 选项实施计划以更新统计信息。

根据数据库统计信息过期的方式,您可能需要在更新数据库统计信息后,通过运行DBCC FREEPROCCACHE命令来清除查询计划缓存。 您将在DBCC FREEPROCCACHE (transact-sql)中找到此过程的语法和参数。 这样做可确保新查询在数据库统计信息更新后使用最佳执行计划。 例如,请参阅以下查询:

-- Remove all elements from the plan cache  
DBCC FREEPROCCACHE  

重要

运行 DBCC FREEPROCCACHE 命令将清除 SQL 实例中的所有查询计划的缓存。 在生产时间内执行此命令之前,应充分理解此命令。

如果在更新过时的数据库统计信息之后未执行DBCC FREEPROCCACHE命令,则具有低效执行计划的查询可能仍驻留在缓存中并可供使用。 如果是这种情况,请使用存储过程强制在指定存储过程上重新编译(请参阅sp_recompile (transact-sql))。 例如,请参阅以下查询:

USE SP2013_Content_DB  
GO  
sp_recompile proc_getwebnavstruct  

同时运行sp_recompile命令和过程、函数或表参数将在缓存中的单个元素作为删除的目标,而不会影响实例。

是否仍需要帮助? 转到SharePoint 社区