sys.dm_db_stats_histogram(Transact-SQL)

适用于:SQL Server 2016 (13.x) 及更高版本Azure SQL 数据库Azure SQL 托管实例

返回当前 SQL Server 数据库中指定数据库对象(表或索引视图)的统计信息直方图。 类似于 DBCC SHOW_STATISTICS WITH HISTOGRAM

注意

此 DMF 自 SQL Server 2016 (13.x) SP1 CU2 起开始提供

语法

sys.dm_db_stats_histogram (object_id , stats_id)

参数

object_id

请求其中一个统计信息的属性的当前数据库中对象的 ID。 object_idint

stats_id

指定 object_id的统计信息的 ID。 可以从 sys.stats 动态管理视图获取该统计信息 ID。 stats_idint

返回的表

列名称 数据类型 说明
object_id int 要返回统计信息对象属性的对象(表或索引视图)的 ID。
stats_id int 统计信息对象的 ID。 在表或索引视图中是唯一的。 有关详细信息,请参阅 sys.stats
step_number int 直方图中的梯级数。
range_high_key sql_variant 直方图梯级的上限列值。 列值也称为键值。
range_rows real 其列值位于直方图梯级内(不包括上限)的行的估算数目。
equal_rows real 其列值等于直方图梯级的上限的行的估算数目。
distinct_range_rows bigint 非重复列值位于直方图梯级内(不包括上限)的行的估算数目。
average_range_rows real 直方图步骤中具有重复列值的平均行数,不包括上限(RANGE_ROWS / DISTINCT_RANGE_ROWSDISTINCT_RANGE_ROWS > 0)。

注解

sys.dm_db_stats_histogram 的结果集返回类似于 DBCC SHOW_STATISTICS WITH HISTOGRAM 的信息,还包括 object_idstats_idstep_number

由于列 range_high_key 是sql_variant数据类型,因此可能需要使用 CAST 谓词,或者 CONVERT 谓词是否与非字符串常量进行比较。

直方图

直方图度量数据集中每个非重复值的出现频率。 查询优化器根据统计信息对象第一个键列中的列值来计算直方图,它选择列值的方法是以统计方式对行进行抽样或对表或视图中的所有行执行完全扫描。 如果直方图是从一组抽样行创建的,则非重复值的行数和非重复值数的存储总计是估计值,不需要是整个整数。

若要创建直方图,查询优化器将对列值进行排序,计算与每个非重复列值匹配的值数,然后将列值聚合到最多 200 个连续直方图梯级中。 每个梯级都包含一个列值范围,后跟上限列值。 该范围包括介于两个边界值之间的所有可能列值,但不包括边界值自身。 最小排序列值是第一个直方图梯级的上限值。

下面的关系图显示包含六个梯级的直方图。 第一个上限值左侧的区域是第一个梯级。

从采样列值计算直方图的示意图。

对于每个直方图梯级:

  • 粗线表示上限值 (range_high_key) 和上限值的出现次数 (equal_rows)

  • range_high_key 左侧的纯色区域表示列值范围和每个列值的平均出现次数 (average_range_rows)。 第一个直方图梯级的 average_range_rows 始终是 0。

  • 点线表示用于估计范围中的非重复值总数 (distinct_range_rows) 和范围中的总指数 (range_rows)。 查询优化器使用 range_rowsdistinct_range_rows 来计算 average_range_rows ,并且不存储采样的值。

查询优化器按照直方图梯级的统计重要性来定义直方图梯级。 它使用最大差异算法使直方图中的梯级减至最少,并同时最大化边界值之间的差异。 最大梯级数为 200。 直方图梯级数可以少于非重复值的数目,即使对于边界点少于 200 的列也是如此。 例如,具有 100 个非重复值的列所具有的直方图的边界点可以少于 100。

权限

要求用户对统计信息列或用户拥有表或用户拥有该表的权限,或者用户是 sysadmin 固定服务器角色、 db_owner 固定数据库角色或 db_ddladmin 固定数据库角色的成员。

示例

A. 基本示例

以下示例创建并填充基本表。 然后,在 Region_Name 列上创建统计信息。

CREATE TABLE Region
(
    Region_ID INT IDENTITY PRIMARY KEY,
    Region_Name VARCHAR (120) NOT NULL
);

INSERT Region (Region_Name)
VALUES ('Canada'), ('Denmark'), ('Iceland'), ('Peru');

CREATE STATISTICS Region_Stats ON Region(Region_Name);

主键占用 stat_id 数字 1,因此对 sys.dm_db_stats_histogram 数字 2 调用 stat_id,以对 Region 表返回统计信息直方图。

SELECT * FROM sys.dm_db_stats_histogram(OBJECT_ID('Region'), 2);

B. 有用的查询

SELECT hist.step_number,
       hist.range_high_key,
       hist.range_rows,
       hist.equal_rows,
       hist.distinct_range_rows,
       hist.average_range_rows
FROM sys.stats AS s
CROSS APPLY sys.dm_db_stats_histogram(s.[object_id], s.stats_id) AS hist
WHERE s.[name] = N'<statistic_name>';

°C 有用的查询

以下示例从表 Region 中进行选择,并在列 Region_Name 上使用谓词。

SELECT * FROM Region
WHERE Region_Name = 'Canada';

以下示例可查看先前在表 Region 和列 Region_Name 上创建的统计信息,以了解与上面查询中的谓词匹配的直方图步骤。

SELECT ss.name,
       ss.stats_id,
       shr.steps,
       shr.rows,
       shr.rows_sampled,
       shr.modification_counter,
       shr.last_updated,
       sh.range_rows,
       sh.equal_rows
FROM sys.stats AS ss
     INNER JOIN sys.stats_columns AS sc
         ON ss.stats_id = sc.stats_id
        AND ss.object_id = sc.object_id
     INNER JOIN sys.all_columns AS ac
         ON ac.column_id = sc.column_id
        AND ac.object_id = sc.object_id
CROSS APPLY sys.dm_db_stats_properties(ss.object_id, ss.stats_id) AS shr
CROSS APPLY sys.dm_db_stats_histogram(ss.object_id, ss.stats_id) AS sh
WHERE ss.[object_id] = OBJECT_ID('Region')
      AND ac.name = 'Region_Name'
      AND sh.range_high_key = CAST ('Canada' AS CHAR (8));