惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MongoDB | Blog
MongoDB | Blog
J
Java Code Geeks
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
D
DataBreaches.Net
腾讯CDC
GbyAI
GbyAI
I
InfoQ
博客园 - Franky
G
Google Developers Blog
Last Week in AI
Last Week in AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Visual Studio Blog
Vercel News
Vercel News
博客园_首页
MyScale Blog
MyScale Blog
Martin Fowler
Martin Fowler
N
Netflix TechBlog - Medium
V
V2EX
T
The Blog of Author Tim Ferriss
M
MIT News - Artificial intelligence
雷峰网
雷峰网
H
Hackread – Cybersecurity News, Data Breaches, AI and More
大猫的无限游戏
大猫的无限游戏
The GitHub Blog
The GitHub Blog

博客园 - tohen

浏览器视频文件分段缓存合并成完整的视频 我爷爷吸烟,我爸爸也吸烟,轮到我不能断了香火 线程封装组件(BackgroundWorker)和线程(Thread) SQL2008R2的 遍历所有表更新统计信息 和 索引重建 试试SQLServer 2014的内存优化表 Sql server2014 内存优化表 本地编译存储过程 SQL Server 2016 查询存储性能优化小结 测试创建表变量对IO的影响 公用表表达式(CTE) 获取应用程序根目录物理路径(Web and Windows) 【别人的老师VS你的老师 】同样是老师,差别怎么这么大呢!? SQL Server 用SSMS查看依赖关系有时候不准确,改用代码查 SQL Server 百万级数据提高查询速度的方法 SQL server 数据库备份还原Sql 在计算列中创建索引提高性能 SQL Server读懂语句运行的统计信息 SET STATISTICS TIME IO PROFILE ON SQL Server对Xml字段的操作 为什么洗澡时你会灵感乍现 SQL Server存储过程中使用表值作为输入参数示例
对比:重建索引与更新统计
tohen · 2017-09-12 · via 博客园 - tohen

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

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
 

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

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