CREATE STATISTICS (Transact-SQL)

对表或索引视图的一列或多列创建查询优化统计信息,包括筛选的统计信息。对于大多数查询,查询优化器已为高质量查询计划生成必要的统计信息;在少数情况下,您需要使用 CREATE STATISTICS 创建附加的统计信息或修改查询设计以提高查询性能。

筛选的统计信息可以提高从定义完善的数据子集选择数据的查询的查询性能。筛选的统计信息在 WHERE 子句中使用筛选谓词来选择统计信息中包括的数据子集。CREATE STATISTICS 可以使用 tempdb 来将行样本排序以便生成统计信息。

有关统计信息的详细信息,包括何时使用 CREATE STATISTICS,请参阅使用统计信息提高查询性能

主题链接图标Transact-SQL 语法约定

语法

CREATE STATISTICS statistics_name 
ON { table_or_indexed_view_name } ( column [ ,...n ] ) 
    [ WHERE <filter_predicate> ]
    [ WITH 
        [ [ FULLSCAN 
          | SAMPLE number { PERCENT | ROWS } 
          | STATS_STREAM = stats_stream ] [ , ] ] 
        [ NORECOMPUTE ] 
    ] ;

<filter_predicate> ::= 
    <conjunct> [AND <conjunct>]

<conjunct> ::=
    <disjunct> | <comparison>

<disjunct> ::=
        column_name IN (constant ,…)

<comparison> ::=
        column_name <comparison_op> constant

<comparison_op> ::=
    IS | IS NOT | = | <> | != | > | >= | !> | < | <= | !<

参数

  • statistics_name
    要创建的统计信息的名称。

  • table_or_indexed_view_name
    要对其创建统计信息的表或索引视图的名称。通过指定限定的表名,可以对另一个数据库中的表或索引视图创建统计信息。

  • column [ ,…n]
    指定要在对其创建统计信息的键列或键列的列表。您可以指定任何可指定为索引键列的列,但下列情况除外:

    • 不能指定 xml、全文和 FILESTREAM 列。

    • 只有当 ARITHABORT 和 QUOTED_IDENTIFIER 数据库设置为 ON 时,才能指定计算列。

    • 如果 CLR 用户定义类型支持二进制排序,则可以指定 CLR 用户定义类型列。如果方法具有确定性标记,可以指定定义为用户定义类型的列的方法调用的计算列。有关创建 CLR 用户定义类型的列的详细信息,请参阅使用 CLR 用户定义类型

  • WHERE <filter_predicate>
    指定一个表达式,以选择在创建统计信息对象时要包括的行的子集。使用筛选谓词创建的统计信息称作筛选统计信息。筛选谓词使用简单比较逻辑且不能引用计算列、UDT 列、空间数据类型列或 hierarchyID 数据类型列。比较运算符不允许使用 NULL 文本的比较。请改用 IS NULL 和 IS NOT NULL 运算符。

    下面是 Production.BillOfMaterials 表的筛选谓词的一些示例:

    WHERE StartDate > '20040101' AND EndDate <= '20040630'

    WHERE ComponentID IN (533, 324, 753)

    WHERE StartDate IN ('20040404', '20040905') AND EndDate IS NOT NULL

    有关筛选谓词的详细信息,请参阅筛选索引设计准则

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

  • SAMPLE number { PERCENT | ROWS }
    指定在查询优化器创建统计信息时所使用的表或索引视图中的近似行百分比或行数。对于 PERCENT,number 可以介于 0 到 100 之间;对于 ROWS,number 可以介于 0 到总数行之间。查询优化器抽样的实际行百分比或行数可能与指定的行百分比或行数不匹配。例如,查询优化器扫描数据页上的所有行。

    对于基于默认抽样的查询计划并非最佳的特殊情况,SAMPLE 非常有用。在大多数情况下,不必指定 SAMPLE,这是因为在默认情况下,查询优化器已根据需要采用抽样,并以统计方式确定大量样本的大小,以便创建高质量的查询计划。

    SAMPLE 不能与 FULLSCAN 选项一起使用。如果未指定 SAMPLE 和 FULLSCAN,查询优化器则默认使用抽样数据并计算样本大小。

    我们建议不指定 0 PERCENT 或 0 ROWS。如果指定 0 PERCENT 或 0 ROWS,则将创建统计信息对象,但该对象不包含任何统计信息数据。

  • NORECOMPUTE
    为 statistics_name 禁用自动统计信息更新选项 AUTO_STATISTICS_UPDATE。如果指定此选项,则查询优化器将完成 statistics_name 的任何正在进行中的统计信息更新并禁用将来的更新。

    若要重新启用统计信息更新,请使用 DROP STATISTICS 删除统计信息,然后运行 CREATE STATISTICS 但不使用 NORECOMPUTE 选项。

    注意事项注意

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

    有关 AUTO_STATISTICS_UPDATE 选项的详细信息,请参阅 ALTER DATABASE SET 选项 (Transact-SQL)。有关禁用和重新启用统计信息更新的详细信息,请参阅使用统计信息提高查询性能

  • STATS_STREAM **=**stats_stream
    标识为仅供参考。不提供支持。不保证以后的兼容性。

注释

每个统计信息对象至多可列出 32 列。

何时使用 CREATE STATISTICS

有关何时使用 CREATE STATISTICS 的详细信息,请参阅使用统计信息提高查询性能

筛选统计信息的引用依赖项

sys.sql_expression_dependencies 目录视图将筛选统计信息谓词中的每一列作为一个引用依赖项跟踪。由于您无法删除、重命名或修改在筛选统计信息谓词中定义的表列的定义,因此在创建筛选统计信息之前应考虑清楚要对表列执行哪些操作。

权限

要求 ALTER TABLE 权限,或者用户必须是表或索引视图的所有者,或者用户必须是 db_ddladmin 固定数据库角色之一的成员。

示例

A. 将 CREATE STATISTICS 与 SAMPLE number PERCENT 一起使用

下面的示例使用 AdventureWorks2008R2 数据库的 Person 表的 BusinessEntityID 和 EmailAddress 列的 5% 作为随机抽样来创建 ContactMail1 统计信息。

USE AdventureWorks2008R2;
GO
CREATE STATISTICS ContactMail1
    ON Person.Person (BusinessEntityID, EmailPromotion)
    WITH SAMPLE 5 PERCENT;

B. 将 CREATE STATISTICS 与 FULLSCAN 和 NORECOMPUTE 一起使用

下面的示例对 Person 表的 BusinessEntityID 和 EmailAddress 列中的所有行创建 ContactMail2 统计信息,并禁用自动重新计算统计信息。

CREATE STATISTICS NamePurchase
    ON AdventureWorks2008R2.Person.Person (BusinessEntityID, EmailPromotion)
    WITH FULLSCAN, NORECOMPUTE;

C. 使用 CREATE STATISTICS 创建筛选统计信息

下面的示例创建筛选统计信息 ContactPromotion1。数据库引擎对 50% 的数据进行采样,然后选择 EmailPromotion 等于 2 的行。

USE AdventureWorks2008R2;
GO
IF EXISTS (SELECT name FROM sys.stats
    WHERE name = N'ContactPromotion1'
    AND object_id = OBJECT_ID(N'Person.Person'))
DROP STATISTICS Person.Person.ContactPromotion1
GO
CREATE STATISTICS ContactPromotion1
    ON Person.Person (BusinessEntityID, LastName, EmailPromotion)
WHERE EmailPromotion = 2
WITH SAMPLE 50 PERCENT;
GO