UPDATE STATISTICS (Transact-SQL)
适用于:Microsoft Fabric Microsoft Fabric
Warehouse 中的 SQL Server
Azure SQL 数据库
Azure SQL 托管实例
Azure Synapse
Analytics Analytics Platform System (PDW)
SQL Analytics 终结点
更新表或索引视图的查询优化统计信息。 默认情况下,查询优化器已根据需要更新统计信息以改进查询计划;但在某些情况下,可以通过使用 UPDATE STATISTICS
或存储过程 sp_updatestats 来比默认更新更频繁地更新统计信息,提高查询性能。
更新统计信息可确保查询使用最新的统计信息进行编译。 通过任何过程更新统计信息可能会导致查询计划自动重新编译。 我们建议不要太频繁地更新统计信息,因为需要在改进查询计划和重新编译查询所用时间之间权衡性能。 具体的折衷方案取决于你的应用程序。 UPDATE STATISTICS
可以使用 tempdb
对行样本进行排序以生成统计信息。
注意
有关 Microsoft Fabric 中的统计信息的详细信息,请参阅 Microsoft Fabric 中的统计信息。
语法
-- Syntax for SQL Server and Azure SQL Database
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_contant ]
-- Syntax for Azure Synapse Analytics and Parallel Data Warehouse
UPDATE STATISTICS [ schema_name . ] table_name
[ ( { statistics_name | index_name } ) ]
[ WITH
{
FULLSCAN
| SAMPLE number PERCENT
| RESAMPLE
}
]
[;]
-- Syntax for Microsoft Fabric
UPDATE STATISTICS [ schema_name . ] table_name
[ ( { statistics_name } ) ]
[ WITH
{
FULLSCAN
| SAMPLE number PERCENT
}
]
[;]
注意
若要查看 SQL Server 2014 (12.x) 及更早版本的 Transact-SQL 语法,请参阅早期版本文档。
注意
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 为 ON 时创建的单列统计信息以及为索引创建的统计信息。
有关 AUTO_CREATE_STATISTICS 的详细信息,请参阅 ALTER DATABASE SET 选项。 若要查看某一表或视图的所有索引,可以使用 sp_helpindex。
FULLSCAN
通过扫描表或索引视图中的所有行来计算统计信息。 FULLSCAN 和 SAMPLE 100 PERCENT 的结果相同。 FULLSCAN 不能与 SAMPLE 选项一起使用。
SAMPLE number { PERCENT | ROWS }
指定当查询优化器更新统计信息时要为其使用的表或索引视图中近似的百分比或行数。 对于 PERCENT,number 可以介于 0 到 100 之间,对于 ROWS,number 可以介于 0 到总行数之间 。 查询优化器抽样的实际行百分比或行数可能与指定的行百分比或行数不匹配。 例如,查询优化器扫描数据页上的所有行。
对于基于默认抽样的查询计划并非最佳的特殊情况,SAMPLE 非常有用。 在大多数情况下,不必指定 SAMPLE,这是因为在默认情况下,查询优化器根据需要采用抽样,并以统计方式确定大量样本的大小,以便创建高质量的查询计划。
注意
在 SQL Server 2016(13.x)中使用数据库兼容性级别 130 时,并行执行用于生成统计信息的数据采样以提高统计信息收集的性能。 每当表大小超过特定阈值时,查询优化器都将使用并行示例统计信息。 从 SQL Server 2017(14.x)开始,无论数据库兼容级别如何,该行为都会更改回使用串行扫描,以避免出现过多 LATCH 等待的潜在性能问题。 更新统计信息时的其余查询计划将保持并行执行(如果限定)。
SAMPLE 不能与 FULLSCAN 选项一起使用。 如果未指定 SAMPLE 和 FULLSCAN,查询优化器则默认使用抽样数据并计算样本大小。
我们建议不指定 0 PERCENT 或 0 ROWS。 如果指定 0 PERCENT 或 0 ROWS,则将更新统计信息对象,但该对象不包含任何统计信息数据。
对于大多数工作负载,不需要完全扫描,默认采样已经足够。 但是,对广泛变化的数据分布敏感的某些工作负载可能需要增加样本大小,或者甚至需要完全扫描。 虽然完全扫描的报价单可能比采样扫描更准确,但复杂的计划可能并没有大幅受益。
有关详细信息,请参阅统计信息的组件和概念。
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_STATISTICS 和 sys.dm_db_stats_properties 公开选定统计信息的持久样本百分比值。
如果执行 AUTO_UPDATE_STATISTICS,则在可用情况下使用持久采样百分比,否则使用默认采样百分比。 此选项不影响 RESAMPLE 行为。
如果该表被截断,则截断的堆或B 树 (HoBT) 上生成的所有统计信息将恢复为使用默认采样百分比。
注意
在 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 选项行为,请不使用 NORECOMPUTE 选项再次运行 UPDATE STATISTICS,或运行 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 服务器配置选项。 使用 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
的详细信息,请参阅何时更新统计信息。
限制
- 外部表格中不支持更新统计信息。 若要更新外部表格中的统计信息,请删除并重新创建统计信息。
MAXDOP
选项与STATS_STREAM
、ROWCOUNT
和PAGECOUNT
选项不兼容。- 如果使用的话,
MAXDOP
选项会受资源调控器工作负载组MAX_DOP
设置的限制。
使用 sp_updatestats 更新所有统计信息
有关如何为数据库中的所有用户定义表和内部表更新统计信息的信息,请参阅存储过程 sp_updatestats。 例如,以下命令调用 sp_updatestats
来更新数据库的所有统计信息。
EXEC 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
表中的 ProductNumber
和 Product
列的统计信息。
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. 更新表的统计信息
以下示例更新 Customer
表的 CustomerStats1
统计信息。
UPDATE STATISTICS Customer (CustomerStats1);
F. 使用完全扫描更新统计信息
以下示例基于扫描 Customer
表中的所有行来更新 CustomerStats1
统计信息。
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
相关内容
- 统计信息
- Microsoft Fabric 中的统计信息
- ALTER DATABASE (Transact-SQL)
- sys.dm_db_stats_properties (Transact-SQL)
- sys.dm_db_stats_histogram (Transact-SQL)
- CREATE STATISTICS (Transact-SQL)
- DBCC SHOW_STATISTICS (Transact-SQL)
- DROP STATISTICS (Transact-SQL)
- sp_autostats (Transact-SQL)
- sp_updatestats (Transact-SQL)
- STATS_DATE (Transact-SQL)