UPDATE STATISTICS (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsAnalytics Platform System (PDW)Microsoft Fabric 中的 SQL 终结点Microsoft Fabric 中的仓库Microsoft Fabric SQL 数据库

更新表或索引视图的查询优化统计信息。 默认情况下,查询优化器已根据需要更新统计信息以改进查询计划;但在某些情况下,可以通过使用 UPDATE STATISTICS 或存储过程 sp_updatestats 来比默认更新更频繁地更新统计信息,提高查询性能。

更新统计信息可确保查询使用最新的统计信息进行编译。 通过任何进程更新统计信息可能会导致查询计划自动重新编译。 我们建议不要太频繁地更新统计信息,因为需要在改进查询计划和重新编译查询所用时间之间权衡性能。 具体的折衷方案取决于你的应用程序。 UPDATE STATISTICS 可以使用 tempdb 对行样本进行排序以生成统计信息。

注意

有关 Microsoft Fabric 中的统计信息的详细信息,请参阅 Fabric 数据仓库中的统计信息

Transact-SQL 语法约定

语法

SQL Server 和 Azure SQL 数据库的语法。

UPDATE STATISTICS table_or_indexed_view_name
    [
        {
            { index_or_statistics__name }
          | ( { index_or_statistics_name } [ , ...n ] )
                }
    ]
    [ WITH
        [
            FULLSCAN
              [ [ , ] PERSIST_SAMPLE_PERCENT = { ON | OFF } ]
            | SAMPLE number { PERCENT | ROWS }
              [ [ , ] PERSIST_SAMPLE_PERCENT = { ON | OFF } ]
            | RESAMPLE
              [ ON PARTITIONS ( { <partition_number> | <range> } [ , ...n ] ) ]
            | <update_stats_stream_option> [ , ...n ]
        ]
        [ [ , ] [ ALL | COLUMNS | INDEX ]
        [ [ , ] NORECOMPUTE ]
        [ [ , ] INCREMENTAL = { ON | OFF } ]
        [ [ , ] MAXDOP = max_degree_of_parallelism ]
        [ [ , ] AUTO_DROP = { ON | OFF } ]
    ] ;

<update_stats_stream_option> ::=
    [ STATS_STREAM = stats_stream ]
    [ ROWCOUNT = numeric_constant ]
    [ PAGECOUNT = numeric_constant ]

Azure Synapse Analytics 和并行数据仓库的语法。

UPDATE STATISTICS [ schema_name . ] table_name
    [ ( { statistics_name | index_name } ) ]
    [ WITH
       {
              FULLSCAN
            | SAMPLE number PERCENT
            | RESAMPLE
        }
    ]
[;]

Microsoft Fabric 的语法。

UPDATE STATISTICS [ schema_name . ] table_name
    [ ( { statistics_name } ) ]
    [ WITH
       {
              FULLSCAN
            | SAMPLE number PERCENT
        }
    ]
[;]

注意

Azure Synapse Analytics 中的无服务器 SQL 池不支持此语法。

参数

table_or_indexed_view_name

包含统计信息对象的表或索引视图的名称。

index_or_statistics_name 或 statistics_name | index_name 或 statistics_name

要更新统计信息的索引的名称或要更新的统计信息的名称。 如果未指定 index_or_statistics_name 或 statistics_name,查询优化器将更新表或索引视图的所有统计信息。 这包括使用 CREATE STATISTICS 语句创建的统计信息、创建时间 AUTO_CREATE_STATISTICS 创建的单列统计信息以及为索引创建的统计信息。

有关详细信息 AUTO_CREATE_STATISTICS,请参阅 ALTER DATABASE SET 选项。 若要查看某一表或视图的所有索引,可以使用 sp_helpindex

FULLSCAN

通过扫描表或索引视图中的所有行来计算统计信息。 FULLSCANSAMPLE 100 PERCENT 具有相同的结果。 FULLSCAN 不能与该选项一起使用 SAMPLE

SAMPLE number { PERCENT | ROWS }

指定当查询优化器更新统计信息时要为其使用的表或索引视图中近似的百分比或行数。 对于PERCENT数字可以是 0 到 100,对于ROWS,数字可以是 0 到总行数。 查询优化器抽样的实际行百分比或行数可能与指定的行百分比或行数不匹配。 例如,查询优化器扫描数据页上的所有行。

SAMPLE 对于基于默认采样的查询计划不是最佳情况的特殊情况非常有用。 在大多数情况下,不需要指定 SAMPLE ,因为查询优化器默认使用采样并确定统计显著样本大小,因为需要创建高质量的查询计划。

注意

在 SQL Server 2016(13.x)中使用数据库兼容性级别 130 时,并行执行用于生成统计信息的数据采样以提高统计信息收集的性能。 每当表大小超过特定阈值时,查询优化器都将使用并行示例统计信息。 从 SQL Server 2017(14.x)开始,无论数据库兼容级别如何,行为都会更改回使用串行扫描,以避免出现过多 LATCH 等待的潜在性能问题。 更新统计信息时的其余查询计划将保持并行执行(如果限定)。

SAMPLE 不能与该选项一起使用 FULLSCAN 。 如果两者SAMPLEFULLSCAN均未指定,查询优化器将使用采样数据,并默认计算样本大小。

建议不指定 0 PERCENT0 ROWS0 ROWS指定或指定统计信息对象时0 PERCENT,将更新统计信息对象,但不包含统计信息数据。

对于大多数工作负载,不需要完全扫描,默认采样已经足够。 但是,某些对广泛不同数据分布敏感的工作负荷可能需要增加样本大小,甚至完全扫描。 虽然完整扫描的估计值可能比采样扫描更准确,但复杂的计划可能没有显著优势。

有关详细信息,请参阅统计信息的组件和概念

RESAMPLE

使用最近的采样速率更新每个统计信息。

使用 RESAMPLE 可能会导致全表扫描。 例如,索引的统计信息使用全表扫描来获取其采样速率。 如果未指定任何示例选项(SAMPLE,, FULLSCAN), RESAMPLE查询优化器会采样数据,并默认计算样本大小。

不支持在 Microsoft Fabric RESAMPLE 中的仓库中。

PERSIST_SAMPLE_PERCENT = { ON | OFF }

适用于:SQL Server 2016 (13.x) Service Pack 1 CU4、SQL Server 2017 (14.x) Service Pack 1 或 SQL Server 2019 (15.x) 及更高版本、Azure SQL 数据库、Azure SQL 托管实例

ON,统计信息将保留未显式指定采样百分比的后续更新的设置采样百分比。 当 OFF,统计信息采样百分比将在未显式指定采样百分比的后续更新中重置为默认采样。 默认值为 OFF

DBCC SHOW_STATISTICSsys.dm_db_stats_properties 公开选定统计信息的持久样本百分比值。

如果 AUTO_UPDATE_STATISTICS 已执行,则使用持久采样百分比(如果可用),否则使用默认采样百分比。 RESAMPLE 行为不受此选项影响。

如果该表被截断,则截断的堆或B 树 (HoBT) 上生成的所有统计信息将恢复为使用默认采样百分比。 同样,如果在没有行的对象上更新统计信息,即使以前配置过,它也会恢复为使用默认采样百分比 PERSIST_SAMPLE_PERCENT

注意

在 SQL Server 中,重新生成以前更新了统计信息 PERSIST_SAMPLE_PERCENT的索引时,持久化的示例百分比将重置回默认值。 从 2016 SQL Server 2016 (13.x) SP2 CU17、SQL Server 2017 (14.x) CU26 和 SQL Server 2019 (15.x) CU10 开始,即使在重新生成索引时,也会保留持久的采样百分比。

ON PARTITIONS ( { <partition_number> | <range> } [ , ...n ] ) ]

适用于:SQL Server 2014 (12.x) 及更高版本

强制重新计算子句中指定的 ON PARTITIONS 分区的叶级统计信息,然后合并以生成全局统计信息。 WITH RESAMPLE 是必需的,因为使用不同采样率生成的分区统计信息不能合并在一起。

ALL | COLUMNS | INDEX

更新所有现有统计信息、在一列或多列上创建的统计信息或为索引创建的统计信息。 如果未指定任何选项,则 UPDATE STATISTICS 语句将更新表或索引视图的所有统计信息。

NORECOMPUTE

为指定的统计信息禁用自动统计信息更新选项 AUTO_UPDATE_STATISTICS。 如果指定此选项,则查询优化器将完成此统计信息更新并禁用将来的更新。

若要重新启用 AUTO_UPDATE_STATISTICS 选项行为,请再次运行 UPDATE STATISTICS ,而不 NORECOMPUTE 运行该选项或运行 sp_autostats

警告

使用此选项可能会产生并非最佳的查询计划。 建议您尽量少用此选项,并且此选项只能由有资格的系统管理员使用。

有关该选项的详细信息 AUTO_STATISTICS_UPDATE ,请参阅 ALTER DATABASE SET 选项

INCREMENTAL = { ON | OFF }

适用于:SQL Server 2014 (12.x) 及更高版本

ON,根据分区统计信息重新创建统计信息。 删除统计信息树时 OFF,SQL Server 会重新计算统计信息。 默认值为 OFF

如果不支持每个分区统计信息,将生成错误。 对于以下统计信息类型,不支持增量统计信息:

  • 使用与基表不分区对齐的索引创建的统计信息。
  • 对 Always On 可读辅助数据库创建的统计信息。
  • 对只读数据库创建的统计信息。
  • 对筛选的索引创建的统计信息。
  • 对视图创建的统计信息。
  • 对内部表创建的统计信息。
  • 使用空间索引或 XML 索引创建的统计信息。

MAXDOP = max_degree_of_parallelism

适用于:SQL Server(从 SQL Server 2016 (13.x) SP2 和 SQL Server 2017 (14.x) CU3 开始)。

覆盖 max degree of parallelism 统计信息作持续时间的配置选项。 有关详细信息,请参阅 配置 max degree of parallelism 服务器配置选项。 用于 MAXDOP 限制并行计划执行中使用的处理器数。 最大数量为 64 个处理器。

max_degree_of_parallelism 可以是:

1

取消生成并行计划。

>1

根据当前系统工作负荷,将并行统计作中使用的最大处理器数限制为指定数目或更少。

0(默认值)

根据当前系统工作负荷使用实际的处理器数量或更少数量的处理器。

update_stats_stream_option

标识为仅供参考。 不支持。 不保证以后的兼容性。

AUTO_DROP = { ON | OFF }

适用于:SQL Server 2022 (16.x) 及更高版本

目前,如果统计信息是由客户数据库上的第三方工具创建的,则这些统计信息对象可能会阻止或干扰客户可能需要的架构更改。

(从 SQL Server 2022 (16.x)开始) |此功能允许在模式下创建统计信息对象,以便架构更改 不会被统计信息阻止,而是会删除统计信息。 这样,自动删除统计信息的行为类似于自动创建的统计信息的行为。

注意

尝试在自动创建的统计信息上设置或取消设置 Auto_Drop 属性可能会引发错误 - 自动创建的统计信息始终使用自动删除。 还原时,某些备份可能设置此属性不正确,直到下次更新统计信息对象时(手动或自动)。 但是,自动创建的统计信息的行为始终类似于自动删除统计信息的行为。

注解

何时使用 UPDATE STATISTICS

有关何时使用 UPDATE STATISTICS 的详细信息,请参阅何时更新统计信息

限制

  • 外部表格中不支持更新统计信息。 若要更新外部表格中的统计信息,请删除并重新创建统计信息。
  • 不支持更新在每个列存储索引上自动创建的统计信息。 尝试此作会导致错误 35337: UPDATE STATISTICS failed because statistics cannot be updated on a columnstore index. UPDATE STATISTICS is valid only when used with the STATS_STREAM option.
  • MAXDOP 选项与 STATS_STREAMROWCOUNTPAGECOUNT 选项不兼容。
  • 如果使用的话,MAXDOP 选项会受资源调控器工作负载组 MAX_DOP 设置的限制。

使用 sp_updatestats 更新所有统计信息

有关如何为数据库中的所有用户定义表和内部表更新统计信息的信息,请参阅存储过程 sp_updatestats。 例如,以下命令调用 sp_updatestats 来更新数据库的所有统计信息。

EXECUTE sp_updatestats;

自动索引和统计信息管理

使用 自适应索引碎片整理 等解决方案自动管理一个或多个数据库的索引碎片整理和统计信息更新。 此过程会自动选择是根据其碎片级别重新生成还是重新组织索引以及其他参数,并使用线性阈值更新统计信息。

确定上次统计信息更新

若要确定最近一次更新统计信息的时间,请使用 STATS_DATE 函数。

PDW/Azure Synapse Analytics

Analytics Platform System (PDW)/Azure Synapse Analytics 不支持以下语法:

UPDATE STATISTICS t1 (a, b);
UPDATE STATISTICS t1 (a) WITH SAMPLE 10 ROWS;
UPDATE STATISTICS t1 (a) WITH NORECOMPUTE;
UPDATE STATISTICS t1 (a) WITH INCREMENTAL = ON;
UPDATE STATISTICS t1 (a) WITH STATS_STREAM = 0x01;

权限

要求具有对表或视图的 ALTER 权限。

示例

A. 更新表的所有统计信息

以下示例更新 SalesOrderDetail 表的所有统计信息。

USE AdventureWorks2022;
GO

UPDATE STATISTICS Sales.SalesOrderDetail;
GO

B. 更新索引的统计信息

以下示例更新 AK_SalesOrderDetail_rowguid 表的 SalesOrderDetail 索引的统计信息。

USE AdventureWorks2022;
GO

UPDATE STATISTICS Sales.SalesOrderDetail (AK_SalesOrderDetail_rowguid);
GO

C. 通过使用 50% 抽样更新统计信息

以下示例将创建并更新 Name 表中的 ProductNumberProduct 列的统计信息。

USE AdventureWorks2022;
GO

CREATE STATISTICS Products
    ON Production.Product([Name], ProductNumber)
    WITH SAMPLE 50 PERCENT;

-- Time passes. The UPDATE STATISTICS statement is then executed.
UPDATE STATISTICS Production.Product (Products)
    WITH SAMPLE 50 PERCENT;

D. 通过使用 FULLSCAN 和 NORECOMPUTE 更新统计信息

以下示例更新 Products 表中的 Product 统计信息,强制对 Product 表中的所有行进行完全扫描,并关闭 Products 统计信息的自动统计信息功能。

USE AdventureWorks2022;
GO

UPDATE STATISTICS Production.Product (Products)
    WITH FULLSCAN, NORECOMPUTE;
GO

示例:Azure Synapse Analytics 和 Analytics Platform System (PDW)

E. 更新表的统计信息

以下示例更新 CustomerStats1 表的 Customer 统计信息。

UPDATE STATISTICS Customer (CustomerStats1);

F. 使用完全扫描更新统计信息

以下示例基于扫描 CustomerStats1 表中的所有行来更新 Customer 统计信息。

UPDATE STATISTICS Customer (CustomerStats1) WITH FULLSCAN;

G. 更新表的所有统计信息

以下示例更新 Customer 表的所有统计信息。

UPDATE STATISTICS Customer;

H. 将 CREATE STATISTICS 与 AUTO_DROP 配合使用

要使用自动删除统计信息,只需将以下内容添加到统计信息创建或更新的“WITH”子句中。

UPDATE STATISTICS Customer (CustomerStats1) WITH AUTO_DROP = ON;