`
xiebh
  • 浏览: 613071 次
  • 性别: Icon_minigender_1
  • 来自: 太原
社区版块
存档分类
最新评论

索引统计(Index Statistics)

阅读更多
正如前面提到的,键的选择性是决定当执行一个查询时是否使用索引的重要因素。SQL Server在系统表sysindexs的statblob字段中存储了键的选择性和样本直方图的值。查询优化器正是基于索引键对应于该列中的值和查询中的SARG,来决定使用哪个索引。

Statblob列是一个image类型列,为了看到存储在该列中的统计信息,可使用DBCC SHOW_STATISTICS命令,该命令返回下列信息:

  • 一个直方图。它包含了索引键的第一列的偶数个样本值。SQL Server在直方图中至多存储200个样本值。
  • 索引中的组合列的索引密度。索引密度表明了索引键的唯一性,本节随后将讨论。
  • 计算统计信息时表中行数。
  • 用于抽样生成统计信息的行数。
  • 直方图中存储的样本值的个数。
  • 键的平均长度值。
  • 统计计算的日期和时间。


DBCC SHOW_STATISTICS语法如下:

DBCC SHOW_STATISTICS (tablename, index)

Listing 34.1显示了authors表中的在au_lname和au_fname列的aunmind非聚集索引的统计信息。

Dbcc show_statistics (authors, aunmind)
Go


Statistics for INDEX 'aunmind'.
Updated              Rows   Rows Sampled Steps Density    Average key length
-------------------- ------ ------------ ----- ---------- ------------------
Aug  6 2001  1:34AM      23           23    22        0.0          24.52174

All density              Average Length           Columns
------------------------ ------------------------ --------------------------
            4.5454547E-2                7.3913045 au_lname
            4.3478262E-2                 13.52174 au_lname, au_fname
            4.3478262E-2                 24.52174 au_lname, au_fname, au_id

(3 row(s) affected)

RANGE_HI_KEY      RANGE_ROWS   EQ_ROWS      DISTINCT_RANGE_ROWS  AVG_RANGE_ROWS
----------------- ------------ ------------ -------------------- --------------
Bennet                     0.0          1.0                    0            0.0
Blotchet-Halls             0.0          1.0                    0            0.0
Carson                     0.0          1.0                    0            0.0
DeFrance                   0.0          1.0                    0            0.0
del Castillo               0.0          1.0                    0            0.0
Dull                       0.0          1.0                    0            0.0
Green                      0.0          1.0                    0            0.0
Greene                     0.0          1.0                    0            0.0
Gringlesby                 0.0          1.0                    0            0.0
Hunter                     0.0          1.0                    0            0.0
Karsen                     0.0          1.0                    0            0.0
Locksley                   0.0          1.0                    0            0.0
MacFeather                 0.0          1.0                    0            0.0
McBadden                   0.0          1.0                    0            0.0
O'Leary                    0.0          1.0                    0            0.0
Panteley                   0.0          1.0                    0            0.0
Ringer                     0.0          2.0                    0            0.0
Smith                      0.0          1.0                    0            0.0
Straight                   0.0          1.0                    0            0.0
Stringer                   0.0          1.0                    0            0.0
White                      0.0          1.0                    0            0.0
Yokomoto                   0.0          1.0                    0            0.0

分析上面的输出,你能推算出统计最后的修改时间是2001年8月6日。当生成计信息时该表共有23行(Rows),所有23行都用来抽样生成统计信息(Rows Sampled)。键值的平均长度为24.52174字节(Average Key Length)。根据密度信息(Density),你能看到该索引具有高选择性(低密度意味着高选择性——索引密度后面将涉及到)。表中23行数据,其中22行具有唯一值。
在概述信息和索引密度之后,显示了索引直方图。

索引直方图(The Statistics Histogram)

直方图中至多可存储200个样本值。每个样本值称为一个step。保存在每个step中样本值是值的范围的端点。每个step保存了3个值,分别描述为:

  • EQ_ROWS——与样本值相同的行数。换句话就是该step中重复值的个数。
  • RANG_ROWS——表示除了当前值外,介于当前step和前一个step之间其他值的行数。
  • Rang Density——表示在该范围内有多少个不同的值。范围密度信息实际上有两个单独的列组成,分别为:DISTINCT_RANGE_ROWS 和AVG_RANG_ROWS。
  • DISTINCT_RANGE_ROWS表示除了当前值外,当前step与前一个step之间具有多少个不同值的个数。
  • AVG_RANGE_ROWS在该step范围内,每个不同值的平均行数。


在listing34.1的输出中,索引中第一列的所有不同键值的值作为样本值存储在直方图中,所以,直方图中的样本值之间没有值(RANG_ROWS),其后所有的范围值为0。你可能注意到在last name 为Ringer的索引键值上有一个重复值(EQ_ROWS = 2)。为了更好比较,Listing34.2显示了bigpubs2000数据库中的sales表的DBCC SHOW_STATISTICS信息片段。

Listing 34.2 DBCC SHOW_STATISTICS Output for the titleidind Index on the sales Table in the bigpubs2000 Database
Statistics for INDEX 'titleidind'.
Updated              Rows   Rows Sampled Steps Density       Average key length
-------------------- ------ ------------ ----- ------------  ------------------
Aug 21 2001 11:18PM  168725       168725   200 1.8955356E-3           26.405577

(1 row(s) affected)

All density              Average Length           Columns
------------------------ ------------------------ -----------------------------
            1.8621974E-3                      6.0 title_id
             5.997505E-6                     10.0 title_id, stor_id
            5.9268041E-6                26.405577 title_id, stor_id, ord_num

(3 row(s) affected)

RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
------------ ---------- ------- ------------------- -------------------
BI0194              0.0   314.0                   0                 0.0
BI2184            613.0   343.0                   2               306.5
BI2574            270.0   277.0                   1               270.0
BI3224            618.0   286.0                   2               309.0
BI3976            311.0   293.0                   1               311.0
BI6450            673.0   300.0                   2               336.5
BI9506            947.0   292.0                   3           315.66666
BU1111            296.0   299.0                   1               296.0
BU7832            349.0   334.0                   1               349.0
CH0249           1011.0   311.0                   3               337.0
CH0639            984.0   307.0                   3               328.0

...

TC4203              0.0   321.0                   0                 0.0
TC7777              0.0   297.0                   0                 0.0
(200 row(s) affected)

从这个例子你可以看出,每个范围内有更多的值(RANG_ROWS),并且每个step中包含了更多的重复值(EQ_ROWS)。另外,直方图中的所有200行都被使用了,表中的168,725行记录分布在这些200行中。所有的168,725行都被用来生成统计信息(Rows Sampled)。
只有当一个常量表达式与索引列进行比较时,并且常量表达式的值在查询编译时是已知时,SARG的计算才能使用直方图的step值。直方图中的step可以为SARG使用的的例子包括:
Where  col_a  = getddate()
Where cust_id = 12345
Where  monthly_sales < 10000 /12
Where  l_name like "Smith" + "%"

有些常量表达式的直到查询运行时才能计算出来。这些查询参数中包含了局部变量或者子查询:

Where  price  = @avg_price
Where  total_sales > (select sum(qty) from sales)
Where  titles.pub_id = publishers_id

对于这些类型的表达式,你需要其他方法来估计匹配的行数。另外,因为直方图steps只记录了索引中第一列的值,当需要评估组合索引的多列的SARG匹配的行数时,SQL Server必须使用不同方法来决定,例如下面:

Select  * from sales
Where  title_id = 'BI3976'
And stor_id = 'p648'

当直方图没有被使用或者不能使用时,SQL Server使用索引密度值来估计匹配的行数。

索引密度(Index Densities)

当一个查询的SARG 的值直到查询运行时才已知,或者SARG是关于一个索引的多列时,SQL Server才使用为索引中每列存储的密度值。对于组合键值,SQL Server为第一列的组合键存储了密度值;为第一列和第二列;为第一、二、三列;等等。这些信息可以从Listing34.1的DBCC  SHOW_STATISTICS 输出信息的All density区域看到。
索引密度表示为键的唯一键值的倒数。每个键的密度可以按照下面的公式进行计算:

引用
Key density =  1.00/ ( Count of distinct key values in the table)
键密度 = 1.00 / (表中的不同键值数)


所以,pubs数据库的author表中state列的密度计算公式如下:
Select Density = 1.00/ (select count (distinct state) from authors)
Go


Density
----------------
.1250000000000

State和zip的组合列密度计算如下:

Select density = 1.00/( select count (distinct  state + zip) from authors)
Go


Density
----------------
.0555555555555

注意,不像选择率,越小的索引密度意味着具有更高的索引选择性。当密度趋近于1,索引就变得有更少的选择性,基本上没有用处了。当索引的选择性低的时候,优化器可能会选择一个表扫描(table scan),或者叶子级的索引扫描(Index scan),而不会进行索引查找(index seek),因为这样会付出更多的代价。

引用
提示:
当心你的数据库中低选择性的索引。这样的索引通常是对系统的性能是一个损害。它们通常不仅不会用来进行数据的检索,而且也会使得数据修改语句变得缓慢,因为需要额外的索引维护。识别这些索引,考虑删除掉它们。
通常,当你给键中添加更多的列时,密度值应该变得更小。例如,在Listing 34.2,密度值逐渐变小。


Key Column Index Density
title_id 1.8621974E-3
title_id, stor_id 5.997505E-6
title_id, stor_id, ord_num 5.9268041E-6

使用索引密度评估行数(Estimating Rows Using the Index Statistics)

那么优化器是如何使用索引密度来决定一个索引的效果呢?
当在一个范围内查找一个索引值或者键中存在重复值时,SQL Server会使用直方图信息。考虑下面关于bigpubs2000数据库中的sales表中查询:
Select * from sales
Where title_id = 'BI2184'


因为在表中title_id中存在重复值,SQL Server使用关于title_id的直方图(参考Listing34.2)来估计匹配的行数。对于BI2184值,它将查看EQ_ROWS值,值为343.0。这表示在表中title_id值为BI2184的记录共有343行。

当一个查询参数(search argument)的精确匹配(exact match 即等号计算)在直方图中step没有发现时,SQL Server使用比查找值(search value)大的下一个step中的AVG_RANG_ROWS值。例如,SQL Server对查找值为‘BI2187’进行评估,它将会发现匹配值为270.0行。

对一个范围检索,SQL Server把检范围两端的RANG_ROW和EQ_ROWS相加。例如,利用Listing34.2中的直方图,如果查找参数为 where title_id  <= 'BI2574',行数估计将是:
314 + 613 + 343 + 270 + 277,或者为1817。

当直方图不能使用时,SQL Server就使用索引密度来估计匹配行数。对于等值查找的计算公式是直截了当的,例如:
Declare @tid varchar(6)
Select @tid = 'BI2574'
Select  count(*) from sales where title_id = @tid

行估计值等于指定键值的索引密度(1.8621974E-3)乘以表中行数:

Select  count(*) * 1.8621974E-3
From sales
Go

-------------------
314.19925631500001

如果一个查询的SARG为title_id 和stor_id,并且假如title_id的SARG是一个可在优化期间可评价的常量表达式,SQL Server会用title_id stor_id的索引密度和title_id的直方图来估计匹配的行数(对某些值来说,索引密度估计的值可能会大学直方图估计出来的值)。SQL Server 将会用二者中较小的值作为匹配的行数。
根据title_id  stor_id的索引密度,你能看到:

Select coun(*) * 5.997505E-6
From sales

-----------------------------------------------------
                                       1.011929031125
在这个例子中,SQL Server将用title_id 和stor_id的索引密度来估计匹配的值。在此情况下,它估计查询将返回一条匹配的行。

生成和维护索引统计

现在,你也许会问“入户创建索引统计,并且如何维护他们?”当你在一个表上创建一个索引时候索引统计就会第一次被创建,或者当你运行UPDATE STATISTICS 命令时。在7.0以前的版本中,索引统计信息不会自动更新。如果当索引创建之后,你插入许多行,那么反映索引统计的直方图信息不会反映实际的键值分布。结果,优化器有时选择了一个低效率的执行计划。作为一个常规的日常委会工作,DBA只好创建一个schedule运行UPDATE STATISTICS来保持索引统计的及时更新。7.0以后的版本,索引统计会由SQL Server来自动更新。SQL Server不断监视有关索引键的更新活动,并在合适的情况下通过内部的进程来更新统计信息。









分享到:
评论

相关推荐

    Oracle数据库索引的维护

    索引统计信息对于优化查询性能至关重要,主要包括以下几个方面: 1. **统计信息收集**:通过`ANALYZE TABLE ... COMPUTE STATISTICS`或`ANALYZE TABLE ... ESTIMATE STATISTICS`命令来收集表和索引的统计信息。 2. ...

    oracle索引使用样例

    #### 二、表和索引统计信息的收集 收集统计信息对于优化查询计划至关重要。可以通过以下几种方式收集统计信息: 1. **使用`ANALYZE TABLE`命令**: ```sql ANALYZE TABLE GD_YX_ZYTDYH COMPUTE STATISTICS FOR ...

    函数索引使用

    创建索引后,可以通过`ANALYZE INDEX`和`ANALYZE TABLE`命令来计算索引和表的统计信息,这些统计信息对于优化器决定如何执行查询至关重要。 ```sql SQL&gt; analyze index fbionsale_contacts compute statistics; SQL&gt;...

    SQL Server Statistics Primer

    1. **索引统计数据(Index stats)**:这种类型的统计数据是在创建索引时自动生成的,它覆盖了索引键列的数据。这些统计数据可以由以下操作创建: - 通过`CREATE INDEX`语句同步创建。 - 作为约束创建的一部分,比如...

    对SQL Server索引的探讨.pdf

    管理索引包括创建索引、删除索引和更新索引统计信息。创建索引可以使用CREATE INDEX语句,并且可以通过DROP_EXISTING选项删除已存在的同名索引。此外,DBCC SHOWCONTIG可以显示关于索引的存储统计信息,帮助DBA判断...

    oracle索引失效的总结

    - 定期更新索引统计信息(`ANALYZE TABLE ... COMPUTE STATISTICS;`)。 - 使用自动任务(`DBMS_STATS.GATHER_TABLE_STATS`)定期收集统计信息。 #### 3. Cost估算偏差 Oracle优化器会根据成本模型来决定是否使用索引...

    索引维护方法

    `UPDATE STATISTICS`命令用于更新表和索引的统计信息,确保SQL Server能做出准确的执行计划。 4. **监控性能**:Perfmon(Performance Monitor)是Windows系统内置的性能监视工具,可用于收集SQL Server的性能...

    Sybase 数据库查询索引优化

    5. **维护索引**:定期进行索引重建和统计更新,确保索引的碎片最小,保持其高效性。Sybase提供了REORGANIZE INDEX和UPDATE STATISTICS命令来帮助我们完成这些任务。 6. **使用索引提示**:在查询语句中添加索引...

    SQL索引及SQL语句的应用技巧分析.pdf

    (6)使用索引统计信息:使用索引统计信息可以提高查询速度,例如,使用 INDEX_STATISTICS 提示可以获取索引的统计信息。 通过对 SQL 查询的执行过程分析,探讨了 SQL 语句编写和 SQL 索引创建的技巧,可以提高查询...

    Oracle Statistic 统计信息

    3. **索引统计信息 (Index statistics):** - **叶块数 (Number of leaf blocks):** 索引结构中叶节点的块数。 - **层数 (Levels):** 索引的层级深度。 - **聚集因子 (Clustering factor):** 衡量索引顺序与表中...

    SQLServer索引调优实践

    - **聚簇索引(Clustered Index)**:数据行的物理顺序与索引的逻辑顺序相同。也就是说,聚簇索引决定了表中数据的存储顺序。 - **非聚簇索引(Non-Clustered Index)**:数据行的物理顺序与索引的逻辑顺序不同。非聚簇...

    查看mySQL数据库索引

    `INFORMATION_SCHEMA.STATISTICS`表中包含了关于MySQL中所有表的索引统计信息,包括索引名称、索引类型、索引列等。 #### 三、解读`INFORMATION_SCHEMA.STATISTICS`表 `INFORMATION_SCHEMA.STATISTICS`表包含了多...

    Oracle数据库中索引的维护

    分析表及其索引以获取统计信息: - 分析表:`analyze table 表名 compute statistics` - 获取索引中不同关键字的数目:`select distinct_keys from user_indexes where table_name='表名' and index_name='索引名...

    SQL Server中优化其索引的妙招

    为了简化数据库维护,SQL Server提供了数据库维护计划向导(DMPW),可以自动监控和更新索引统计,创建维护计划以定期执行索引优化。这样可以减少手动操作的负担,确保数据库性能始终保持在最佳状态。 综上所述,...

    Best Practices for Gathering Optimizer Statistics with Oralce 18c

    除了常规的表和索引统计信息之外,还可能需要收集其他类型的统计信息,例如分区统计信息、表关联统计信息等。这些统计信息对于更复杂查询的优化非常重要。 - **分区统计信息**:当表被分区时,每个分区都应单独收集...

    查看Sql中自动创建的索引

    2. **统计信息更新**:当执行`UPDATE STATISTICS`命令时,系统可能会创建临时索引来加速统计信息的计算。 3. **自动调整**:SQL Server的自动调整功能会在某些情况下自动创建索引,以提高查询性能。 #### 二、查询...

    oracle索引开发指南

    `COMPUTE STATISTICS`用于收集索引的统计信息,有助于优化器的选择。`COMPRESS`选项允许键压缩,减少重复值的存储空间。`NOSORT`与`REVERSE`控制索引的排序方式,`PARTITION`则用于分区表的索引创建。 索引的主要...

    Oracle DBA实战索引优化

    COMPUTE STATISTICS`命令定期收集统计信息,帮助优化器更好地评估索引的有效性。 3. **索引重构**:对于性能下降明显的索引,可以尝试重建以恢复其效率。 4. **动态SQL**:使用绑定变量代替硬编码的值,有助于优化...

    数据库优化以及操作说明

    索引优化:重建或者重新组织必要的索引 The SQL Server Maintenance Solution lets you intelligently rebuild or reorganize only the indexes that are fragmented. In the IndexOptimize procedure, you can ...

Global site tag (gtag.js) - Google Analytics