设为首页 收藏本站
查看: 719|回复: 0

[经验分享] SQL Server是如何跟踪每一列的修改计数的?

[复制链接]

尚未签到

发表于 2018-10-14 10:24:30 | 显示全部楼层 |阅读模式
  SQL Server是如何跟踪每一列的修改计数的?
  《inside the SQL Server query optimizer》第83页,有这样一段话:
  “
  SQL Server defnes when statistics are out of date by using column modifcation
  counters or colmodctrs, which count the number of table modifcations, and which are
  kept for each table column. Basically, for tables bigger than 500 rows, a statistics object
  is considered out of date if the colmodctr value of the leading column has changed by
  more than 500 plus 20% of the number of rows in the table. The same formula is used
  by fltered statistics but, since they are built only from a subset of the records of the
  table, the colmodctr value is frst adjusted depending on the selectivity of the flter.

  Colmodctrs are usually not exposed by any SQL Server metadata>  accessed by using a dedicated administrator connection and looking at the rcmodified
  column of the sys.sysrscols base system table in SQL Server 2008 (same information
  can be found on the sysrowset columns for SQL Server 2005).
  ”
  下文翻译自:
  http://www.sqlskills.com/blogs/paul/how-are-per-column-modification-counts-tracked/
  从SQLServer 2008开始,SQL Server通过一个隐藏的系统表sys.sysrscols的rcmodified列来跟踪表中每列的修改情况。隐藏的系统表(SQL Server2005时引进,当时我们重写了整个元数据管理系统)只有通过DAC(专用管理员连接)连接方式才能存取,我以前的博文有过介绍:必须使用SQLCMD –A连接或者要在你的连接字符串加上前缀“admin:”。
  列修改情况也能通过sys.system_internals_partition_columns目录视图查看,这种方式不需要DAC方式。
  不过记住,这些完全是基于我的背景知识以及观察而进行推断得出的结论,未来版本中可能会完全改变——因为它是非文档化的,所以你不要基于上面的推断来创建任何程序。
  下面用一个简单表举个例子:
CREATE TABLE t1(c1 INT, c2 INT, c3 INT);  
Go
  我们用DAC查询每一列的修改计数,见下:
SELECT  
p.[object_id],
  
p.[index_id],
  
rs.[rscolid],
  
rs.[rcmodified]
  
FROM sys.sysrscols rs
  
JOIN sys.partitions p
  
ON rs.[rsid] = p.[partition_id]
  
WHERE p.[object_id] = OBJECT_ID ('t1');
  
GO
  查询结果如下:
object_id index_id rscolid rcmodified  
———– ——– ———– ———–
  
277576027 0 1 0
  
277576027 0 2 0
  
277576027 0 3 0
  用sys.system_internals_partition_columns视图查询:
SELECT  
p.[object_id],
  
p.[index_id],
  
pc.[partition_column_id],
  
pc.[modified_count]
  
FROM sys.system_internals_partition_columns pc
  
JOIN sys.partitions p
  
ON pc.[partition_id] = p.[partition_id]
  
WHERE p.[object_id] = OBJECT_ID ('t1');
  
GO
  下面我将一直用DAC直接查询sysrscols。
  如果对表中列做一下修改,然后再运行DAC查询:
INSERT INTO t1VALUES (1, 1, 1);  
GO
object_id index_id rscolid rcmodified  
———– ———– ———– ——————–
  
277576027 0 1 0
  
277576027 0 2 0
  
277576027 0 3 0
  嗯?没有变化嘛!别急,这是因为一些系统表只有在检查点(checkpoint)发生时才会将更新从内存中刷入。我们来试一下,然后再运行DAC查询。
CHECKPOINT;  
GO
object_id index_id rscolid rcmodified  
———– ———– ———– ——————–
  
277576027 0 1 1
  
277576027 0 2 1
  
277576027 0 3 1
  下面仅仅更新c2两次,执行检查点,然后再运行DAC查询。
UPDATE t1 SET c2= 2;  
UPDATE t1 SET c2 = 3;
  
CHECKPOINT;
  
GO
object_id index_id rscolid rcmodified  
———– ———– ———– ——————–
  
277576027 0 1 1
  
277576027 0 2 3
  
277576027 0 3 1
  是不是很酷?
  Sysindexes视图中的rowmodctr列是什么样子呢?它是如何跟踪计数的呢?
  它是记录索引统计的首列自上次统计重建(或初次创建)以来sysrscols.remodified计数的差值。
  下面在表上创建一些简单的索引,然后查一下rowmodctr列:
CREATE NONCLUSTERED INDEX t1_c1_c2 ON t1 (c1, c2);  
CREATE NONCLUSTERED INDEX t1_c3 ON t1 (c3);
  
GO
  
SELECT
  
[name],
  
[rowmodctr]
  
FROM sysindexes
  
WHERE [id] = OBJECT_ID ('t1');
  
GO
name rowmodctr  
—————- ———–
  
NULL 3
  
t1_c1_c2 0
  
t1_c3 0
  第一行是堆的情况,因为我没有建聚集索引。(译者:自表创建以来,该表任何统计首列所发生的修改的总和)
  下面做一些变化,看看sysindexes.rowmodctr 和 sysrscols.rcmodified 是如何变化的。
UPDATE t1 SET c1= 4;  
UPDATE t1 SET c1 = 5;
  
UPDATE t1 SET c1 = 6;
  
UPDATE t1 SET c2 = 2;
  
UPDATE t1 SET c2 = 3;
  
UPDATE t1 SET c3 = 2;
  
CHECKPOINT;
  
GO
object_id index_id rscolid rcmodified  
———– ———– ———– ——————–
  
277576027 0 1 4
  
277576027 0 2 5
  
277576027 0 3 2
  
277576027 2 1 0
  
277576027 2 2 0
  
277576027 2 3 0
  
277576027 3 1 0
  
277576027 3 2 0
name rowmodctr  
—————- ———–
  
NULL 5
  
t1_c1_c2 3
  
t1_c3 1
  因为创建了非聚集索引,所以我对c1进行了3次更新,对c2进行了2次更新,对c3进行了一次更新。相应列的sysrscols.rcmodified计数器都增加了正确的值。但是你会发现它并没有跟踪非聚集索引的列本身。还有,每个非聚集索引的最后一列是一个隐藏的RID列,它指向对应堆中的数据记录。
  但是,sysindexes.rowmodctr却不是按我们想的变化的。我对t1_c1_c2索引中的列分别做了5次修改。然而rowmodctr却只是3。这是因为rowmodctr的算法是跟踪索引统计的首列的sysrscols.rcmodified的变化值。(所以t1_c1_c2索引只是跟踪c1列。)
  为了证明它,我更新统计,对c1做2次修改、对c2做4次修改,然后执行检查点。我们应该发现c1的sysrscols.rcmodified为6,c2的为9;t1_c1_c2的sysindexes.rowmodctr的变为2.
UPDATE STATISTICSt1;  
GO
  
UPDATE t1 SET c1= 7;
  
UPDATE t1 SET c1 = 8;
  
UPDATE t1 SET c2 = 4;
  
UPDATE t1 SET c2 = 5;
  
UPDATE t1 SET c2 = 6;
  
UPDATE t1 SET c2 = 7;
  
CHECKPOINT;
  
GO
object_id index_id rscolid rcmodified  
———– ———– ———– ——————–
  
277576027 0 1 6
  
277576027 0 2 9
  
277576027 0 3 2
  
277576027 2 1 0
  
277576027 2 2 0
  
277576027 2 3 0
  
277576027 3 1 0
  
277576027 3 2 0
name rowmodctr  
—————- ———–
  
NULL 9
  
t1_c1_c2 2
  
t1_c3 0
  就是这样的。即使我们4次更新c2。t1_c1_c2的Sysindexes.rowmodctr也仅仅是2,很明显是c1的sysrscols.rcmodified差值。



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-621390-1-1.html 上篇帖子: Zabbix Server安装部署 下篇帖子: 升级SQL Server2000 sp4 经过
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表