对比:重建索引与更新统计

最近经常被问到的一个问题是关于在数据库维护过程,重建索引与更新统计的执行先后次序。通常,需要考虑以下几点,这里注意的是有两种统计:索引统计、列统计。

1)默认情况下,UPDATE STATISTICS 将会更新索引统计和列统计,如果语句中仅使用了COLUMNS选项,则只更新列统计,若仅使用了INDEX选项,则只更新索引统计

2)默认情况下,UPDATE STATISTICS语句仅采样表的一部分数据,使用UPDATE STATISTICS WITH FULLSCAN则会扫描全表

3)重建索引(如使用ALTER INDEX … REBUILD语句)仅更新索引统计,其效果相当于第2情况(WITH FULLSCAN),重建索引不会更新任何列统计

4)重组索引(如使用ALTER INDEX … REORGANIZE语句)不更新任何统计

综上所述,最简单的情况是:重建索引并更新统计;正如上面提到的,如果重建索引,则索引统计也会通过扫描整个表的行被一同更新,那么只需再运行UPDATE STATISTICS WITH FULLSCAN, COLUMNS语句来更新列统计。

既然第一步仅更新了索引统计,第二步仅更新了列统计,二者执行的先后顺序并不重要。

其他较为复杂的情况是:基于碎片级的重建索引,当然,最坏的情况:如果首先重建了索引(仅扫描整张表的方式更新了索引统计,紧接着使用UPDATE STATISTICS语句(无任何参数),则会又执行了一遍索引统计。

下面通过AdventureWorks示例数据库为例来介绍这些命令的工作方式。

首先运行以下脚本,创建临时表dbo.SalesOrderDetail

SELECT * INTO dbo.SalesOrderDetail FROM sales.SalesOrderDetail

下面使用sys.stats 系统视图来查询新表的统计情况。

SELECT name, auto_created, stats_date(object_id, stats_id) AS update_date FROM sys.stats WHEREobject_id = object_id(‘dbo.SalesOrderDetail‘)

由于是一张新表,并无任何查询,所以没有统计结果,下面执行以下的查询来产生一些统计:

select * from dbo.SalesOrderDetail where SalesOrderID = 43670 and OrderQty =1

再运行先前的查询系统视图的语句,我们会发现系统为SalesOrderID和OrderQty两列创建了以_WA_Sys命名的两个列统计。

下面再运行创建索引的语句:

create index ix_product_id on dbo.SalesOrderDetail ( ProductID)

再运行系统视图的查询:

通过上图中的"auto_created"可以知道哪些统计是由系统创建的,下面运行如下语句只更新列统计,可以通过update_date列来检查。

update statistics SalesOrderDetail with fullscan, columns

接着运行更新索引统计的语句:

update statistics SalesOrderDetail with fullscan, index

下面两条语句的执行效果是一样的(更新索引统计和更统计)

update statistics SalesOrderDetail with fullscan update statistics SalesOrderDetail with fullscan, all


 

下面再运行索引重建的方式来进行比较:

alter index ix_product_id on dbo.SalesOrderDetail rebuild

最后我们来运行“重组索引”检查是否更新了统计:

ALTER INDEX ix_product_id ON dbo.SalesOrderDetail REORGANIZE

由此发现,执行索引重组并未更新任何统计。

时间: 2024-08-06 11:57:48

对比:重建索引与更新统计的相关文章

SQL Server重建索引与重组索引会更新统计信息吗?

在SQL Server中重建索引(Rebuild Index)与重组索引(Reorganize Index)会触发统计信息更新吗? 那么我们先来测试.验证一下: 我们以AdventureWorks2014为测试环境,如下所示: Person.Person表的统计信息最后一次更新为2014-07-17 16:11:31,如下截图所示:   DECLARE @table_name NVARCHAR(32); SET @table_name='Person.Person' SELECT sch.nam

SQL2008R2的 遍历所有表更新统计信息 和 索引重建

---------------------------------------------- [2.以下是更新统计信息] DECLARE UpdateStatisticsTables CURSOR READ_ONLY FOR SELECT sst.name, Schema_name(sst.schema_id) FROM sys.tables sst WHERE sst.TYPE = 'U' DECLARE @name VARCHAR(80), @schema VARCHAR(40) OPEN

ORACLE索引失效,更新统计信息

有时候建立索引的时候不走索引,排除了字段数据问题和sql写法问题之外,应该是统计信息有问题,得重新收集. 一:解锁统计信息 为了稳定执行计划,一般统计信息都会被锁住的,在更新统计信息的时候得先解锁. ①按用户schema解锁: EXEC DBMS_STATS.UNLOCK_schema_STATS('user_name'); ②按表模式解锁:先查出被锁定的表 select table_name from user_tab_statistics where stattype_locked is n

SQLServer 重建索引前后对比

在做维护项目的时,我们经常会遇到索引维护的问题,通过语句,我们就可以判断某个表的索引是否需要重建. 执行一下语句:先分析表的索引 分析表的索引建立情况:DBCC showcontig('Table') DBCC SHOWCONTIG 正在扫描 'Table'' 表...表: 'Table'' (53575229):索引 ID: 1,数据库 ID: 14已执行 TABLE 级别的扫描.- 扫描页数................................: 228- 扫描区数........

ELK学习总结(4-1)elasticsearch更改mapping(不停服务重建索引)

elasticsearch更改mapping(不停服务重建索引)原文 http://donlianli.iteye.com/blog/1924721Elasticsearch的mapping一旦创建,只能增加字段,而不能修改已经mapping的字段.但现实往往并非如此啊,有时增加一个字段,就好像打了一个补丁,一个可以,但是越补越多,最后自己都觉得惨不忍睹了.怎么办??这里有一个方法修改mapping,那就是重新建立一个index,然后创建一个新的mapping.你可能会问,这要是在生产环境,可行

[转]Oracle 重建索引的必要性

http://blog.csdn.net/leshami/article/details/23763963 索引重建是一个争论不休被不断热烈讨论的议题.当然Oracle官方也有自己的观点,我们很多DBA也是遵循这一准则来重建索引,那就是Oracle建议对于索引深度超过4级以及已删除的索引条目至少占有现有索引条目总数的20% 这2种情形下需要重建索引.近来Oracle也提出了一些与之相反的观点,就是强烈建议不要定期重建索引.本文是参考了1525787.1并进行相应描述. 1.重建索引的理由 a.O

第十二章——SQLServer统计信息(4)——在过滤索引上的统计信息

原文:第十二章--SQLServer统计信息(4)--在过滤索引上的统计信息 前言: 从2008开始,引入了一个增强非聚集索引的新功能--过滤索引(filter index),可以使用带有where条件的语句来创建非聚集索引,过滤掉不需要的数据,降低索引的维护开销和存储空间,提高查询性能. 准备工作: 在AdventureWorks2012上,有一个Production.WorkOrder表,将使用这个表来做演示. 步骤: 1.  创建一个非聚集索引在Production.WorkOrder列:

SQL Server 索引碎片产生原理重建索引和重新组织索引

数据库存储本身是无序的,建立了聚集索引,会按照聚集索引物理顺序存入硬盘.既键值的逻辑顺序决定了表中相应行的物理顺序 多数情况下,数据库读取频率远高于写入频率,索引的存在 为了读取速度牺牲写入速度 页 为最小单位 8kb 区 物理连续的页(8页)的集合 内部碎片 数据库页内部产生的碎片,外部反之 碎片的产生: 有一个表里有8条数据,已经将一页填满,这个时候要插入第九条数据,页也就分裂了.这就产生了内部碎片.如下图所示(excel示意一下  懒癌晚期) 注: 不会将9单独分到第二页,索引B+树存储,

为准确生成执行计划更新统计信息-analyze与dbms_stats

如果我们想让CBO利用合理利用数据的统计信息,正确判断执行任何SQL查询时的最快途径,需要及时的使用analyze命令或者dbms_stats重新统计数据的统计信息. 例如索引跳跃式扫描(INDEX SKIP SCAN)例子中,如果不对表EMPLOYEE 及索引收集一下统计信息,就不是INDEX SKIP SCAN策略了. 分析统计信息 analyze table 一般可以指定分析: 表,所有字段,所有索引字段,所有索引. 若不指定则全部都分析. ---table统计信息 analyze tab