首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果表中的所有行都被替换了,为什么不更新统计信息呢?

如果表中的所有行都被替换了,为什么不更新统计信息呢?
EN

Database Administration用户
提问于 2015-03-04 21:31:06
回答 1查看 188关注 0票数 2

我们在Server 2012 SP1实例中有几个“报告”表。每小时,作业都会运行过程,从这些表中删除所有行,然后将当前数据(涉及大量递归和聚合)插入到这些表中。每一行包含数千行。每一张这样的桌子每天都会被查询多次。这些表上的聚集索引和非聚集索引的统计数据显示了94,000%的行进行了更新,最近一次统计数据更新是在几天前。统计信息的自动更新设置为true。

我原以为每次在内容被替换后第一次查询表时,统计数据就会被更新,但这显然是没有发生的。为什么?

EN

回答 1

Database Administration用户

发布于 2016-07-13 17:01:27

不幸的是,在搜索了大约10分钟的SolarWinds‘KB之后,我找不到“无效统计”的度量。这方面的资料会有所帮助。然而,基于您的问题,我将推断,这意味着统计对象可能已经过时,或者已经进行了相当多的修改,而且数据库性能分析器还没有检测到某些类型的更新。如果没有来自产品供应商的更多信息,就很难说了。

话虽如此,但有几件事你应该知道。

首先,您可以验证您的服务器现在发生了什么(例如,当您收到警报时),并将其与您的监视工具进行比较。下面是我使用的脚本:

代码语言:javascript
复制
use [mydatabasename];
go
select 
    [schema_name] = sh.name, 
    [table_name] = t.name, 
    [stat_name] = s.name,
    [column_names] = stuff((
                              select ','+index_col(t.name,sc.stats_id,sc.stats_column_id)
                              from sys.stats_columns sc
                              where sc.object_id = s.object_id
                                and sc.stats_id = s.stats_id    
                               order by sc.stats_column_id        
                              for xml path('')), 1, 1, '' 
                            ) ,
    s.stats_id,     
    sp.last_updated, 
    sp.rows, 
    sp.rows_sampled, 
    sp.unfiltered_rows, 
    [sample_rate] = (100.*sp.rows_sampled)/sp.unfiltered_rows,
    modification_counter,
    [default_mod_threshold] = case when sp.unfiltered_rows < 500
                                                   then 500
                                                   else ( .20
                                                          * sp.unfiltered_rows
                                                          + 500 )
                                              end ,
    [2371_mod_threshold] = sqrt(1000 * sp.unfiltered_rows),
    [default_mod_hit] = case when sp.modification_counter > case
                                                              when sp.unfiltered_rows < 500
                                                              then 500
                                                              else ( .20
                                                              * sp.unfiltered_rows
                                                              + 500 )
                                                              end then 1
                                           else 0
                                      end ,
    [2371_mod_hit] = case when sp.modification_counter > sqrt(1000
                                                              * sp.unfiltered_rows)
                                          then 1
                    end

from sys.stats s 
join sys.tables t 
    on s.object_id = t.object_id
join sys.schemas sh
    on t.schema_id = sh.schema_id
cross apply sys.dm_db_stats_properties(s.object_id,s.stats_id) sp
order by t.name, s.name;

大部分都是不言自明的。但是,我在默认情况下为一个统计对象添加了修改阈值,并包含了TF 2371。默认阈值是一个有趣的计算,而TF 2371是1000 * Table Cardinality的平方根。我包括了一个计算,以包括每个阈值是否已经达到。因此,在警报数据库中运行它,并查看SolarWinds看到的内容是否与当前服务器上发生的情况相匹配。如果不是,那么在某个地方可能会出现一个时间问题,在统计数据更新之前,而是在大量的数据更改之后,就会生成警报。

尽管如此,了解统计数据的AUTO_UPDATE实际上是如何工作的是很重要的。没有一个时钟一样的扫描,通过和不断更新统计数字。相反,在加载statistics对象以编译查询计划时更新统计信息。如果统计数据很少/从不使用,那么它将不会被更新,除非手动更新它,或者如果它碰巧被索引重新构建为索引的依赖对象。但是,如果您有一个从未被使用过的索引,那么情况就完全不同了。

因此,总结如下:

  1. 确认警报是怎么告诉你的
  2. 了解导致统计数据更新的因素
票数 2
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/94429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档