请注意,当 sp_helpindex 输出只显示城市统计 (City) 的一个列时,show_statistics 的输出也会显示 City,Customer_id 列组合的所有密度值。这是因为表中 Customer_id 列上有一个群集的索引,并且每个辅助索引也包含群集的关键字列。通常,这一事实对于用户而言是透明的,但查询优化器会了解群集的列,并且如果执行查询只要求这些列的值在辅助索引的顶部,它会避免辅助获取。统计也包含群集的关键字列。fuckAio2i7L
使用 SQL Server 2000 创建统计
SQL Server 2000 中有两种基本语句会生成上述统计信息:CREATE INDEX 首先会生成声明的索引,然后,作为副产品,它会为组成索引的列组合创建一个统计集;CREATE STATISTICS 只为给定列或列的组合生成统计。 fuckAio2i7L
另外,还有多种方法可以创建统计或索引,但归根结底,每种方法都会发出上述两个命令之一。 fuckAio2i7L
- 使用 sp_createstats 为当前数据库中所有用户表的全部合格列(不包括图像和文本数据)创建统计。如果某个列已经有了直方图,则不会为其创建新的直方图。
- 使用 dbcc dbreindex 为指定数据库中的表重新生成一个或多个索引。
- 在查询分析器中,键入一个查询,选择“显示执行计划”(Show Execution Plan),然后执行查询。在显示的任意图标上单击右键,并选择“管理索引” (Manage Index)或“创建/更新统计信息”(Create/Update Statistics)。
- 使用 Create Index 向导(在其他文章中说明)。
下面是对 pubs..authors 表执行 CREATE STATISTICS 命令的一个示例:fuckAio2i7L
CREATE STATISTICS s1 ON authors (state, au_lname) WITH SAMPLE 50 PERCENT
通常,按默认抽样方式生成的统计最为理想。但有时,使用更大的样本大小来生成统计(理想状况下可以使用 fullscan)有助于查询优化,例如给定列中的值分布不均匀时(某些值频繁出现,而其他值较少出现)。使用较大的样本大小来生成统计,必须以创建统计时所需时间的延长为代价。fuckAio2i7L
上面的命令创建一个两列统计。在本例中,因为表太小,所以会忽略 SAMPLE 50 PERCENT 并执行完全扫描。抽样主要用于避免过多扫描数据,并且只影响具有 1024 或更多页面 (8 MB) 的表和索引。fuckAio2i7L
在 SQL Server 2000 中,创建索引的同时会为所有索引创建统计。SQL Server 在编译查询时自动创建单列统计。这些统计是为优化器必须估算密度或分发的列而创建的。这一规则有两种例外情况:首先,当直接对表执行操作所需的代价小于创建统计所需的代价时,不能为该表创建统计;其次,当服务器过于繁忙(有大量正在进行的重要操作)时,也不能创建统计。fuckAio2i7L
为避免长时间维护未使用过的统计,SQL Server 2000 会记录那些自动创建的统计(仅包括那些不是创建索引的副产品的统计信息)的使用时间。几次自动更新之后,列统计会被放弃而不是被更新。如果将来需要,可以重新创建这些统计。更新统计与创建统计在代价方面并没有实质性的差别。记录使用时间的操作也不会影响用户创建的统计。fuckAio2i7L
通过执行 sp_dboption dbname, 'auto create statistics', 'OFF' 可以在数据库级禁用自动创建统计的功能。fuckAio2i7L
默认情况下,统计是在执行 CREATE STATISTICS 命令或自动创建统计时,通过对数据集进行抽样而创建的。CREATE INDEX 总是会扫描整个数据集,因此最初创建的索引统计并不进行抽样。CREATE STATISTICS 命令允许您通过在 WITH 子句中指定 FULLSCAN 或要扫描的数据百分比来设置样本大小。后者被认为是一个近似值。在 UPDATE STATISTICS 命令上指定 WITH RESAMPLE 时也可以继承上一个样本大小。当既存在索引(通过 fullscan 统计方式创建),其他列(通过 sample 统计方式创建)上又有统计时,






