我最近发现一个堆表有超过 70% 的碎片。所以我决定做一个
ALTER TABLE dbo.myTable REBUILD
Run Code Online (Sandbox Code Playgroud)
有趣的是,之后我有 20% 的碎片。从那以后,那张桌子上再也没有写过。所以我决定再做一次重建。
第2次后桌帽50%碎片化就更厉害了! 我真的不明白这怎么会发生......
我很清楚堆中的转发记录是什么。由于我想将转发记录保留为 0,因此我们决定仅更新无法扩展的列。
最近在我的系统上我遇到了转发记录。
表设计是这样的:
CREATE TABLE dbo.test (
HashValue BINARY(16) NOT NULL,
LoadTime DATETIME NOT NULL,
LoadEndTime DATETIME NULL,
[other columns that never get updates]
) WITH(DATA_COMPRESSION=PAGE);
Run Code Online (Sandbox Code Playgroud)
插入语句总是带来HashValueAND LoadTime。我检查了查询日志。
我插入一个值 '9999-12-31'。
现在系统执行更新LoadTime如下:
;WITH CTE AS (
SELECT *, COALESCE(LEAD(LoadTime) OVER(PARTITION BY HashValue ORDER BY LoadTime) ,'9999-12-31') as EndTimeStamp
)
UPDATE CTE SET LoadEndTime = EndTimeStamp;
Run Code Online (Sandbox Code Playgroud)
由于该LoadEndTime列始终被填充,因此在执行更新时,该行内不应有该列的扩展。它应该是一个就地更新。在那个过程之后我仍然总是得到转发的记录......这对我来说没有意义。
插入语句是这样的:
INSERT INTO dbo.test (HashValue, LoadTime,LoadEndTime)
SELECT HASHBYTES(...), GETDATE(), '1900-01-01'
Run Code Online (Sandbox Code Playgroud)
所以已经有一个虚拟值。即使使用压缩,日期时间 '1900-01-01 00:00:00' 的固定和可变表示应该是 8 个字节。