我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SQL Server是如何跟踪每一列的修改计数的?

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SQL Server是如何跟踪每一列的修改计数的?

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 although they can be

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差值。

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SQL Server是如何跟踪每一列的修改计数的?

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

sql如何修改表列的数据类型

要修改表列的数据类型,可以使用ALTER TABLE语句。例如,要将表中的某一列的数据类型从INT改为VARCHAR,可以使用以下语句:ALTER TABLE table_nameMODIFY column_name VARCHAR(2
sql如何修改表列的数据类型
2024-04-09

什么是时间序列数据SQL Server是如何处理它的

时间序列数据是按时间顺序排列的数据集合,通常用于分析和预测时间相关的趋势和模式。在SQL Server中,时间序列数据可以以多种方式处理,以下是一些常见的方法:使用日期和时间数据类型:SQL Server提供了多种日期和时间数据类型,如DA
什么是时间序列数据SQL Server是如何处理它的
2024-06-03

编程热搜

目录