SQLSERVER中的鬼影索引
SQLSERVER中的鬼影索引
看这篇文章之前可以先看一下鬼影记录
了解了解一下SQLSERVER里的鬼影记录
关于鬼影记录的翻译一
关于鬼影记录的翻译二
当删除表中的某一条记录的时候,索引页面的对应记录并不是马上删除,而是标记为鬼影,当提交事务的时候才真正删除索引记录,
或者回滚事务,鬼影索引记录才会恢复为正常索引记录,这样做的目的就是提高了性能
鬼影索引只会出现在非聚集索引页,聚集索引页是没有鬼影索引的
建立环境
--ghost index record
USE [pratice]
GO
--建表
CREATE TABLE testghostindexnoncluster(id INT IDENTITY(1,1),NAME VARCHAR(20))
GO
--插入记录
INSERT INTO testghostindexnoncluster(name)
SELECT '' UNION ALL
SELECT ''
GO CREATE INDEX IX_testghostindexnoncluster ON testghostindexnoncluster([Id] ASC) SELECT * FROM [dbo].[testghostindexnoncluster]
GO

--TRUNCATE TABLE DBCCResult
INSERT INTO DBCCResult EXEC ('DBCC IND(pratice,testghostindexnoncluster,-1) ') SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC DBCC TRACEON(3604,-1)
GO
DBCC PAGE([pratice],1,15663,1) --索引页
GO
正常情况下的索引页面,Record Type = INDEX_RECORD
DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。 PAGE: (1:15663) BUFFER: BUF @0x03E53304 bpage = 0x1A468000 bhash = 0x00000000 bpageno = (1:15663)
bdbid = 5 breferences = 0 bUse1 = 7847
bstat = 0xc0000b blog = 0x1212121b bnext = 0x00000000 PAGE HEADER: Page @0x1A468000 m_pageId = (1:15663) m_headerVersion = 1 m_type = 2
m_typeFlagBits = 0x0 m_level = 0 m_flagBits = 0x4000
m_objId (AllocUnitId.idObj) = 539 m_indexId (AllocUnitId.idInd) = 256
Metadata: AllocUnitId = 72057594073251840
Metadata: PartitionId = 72057594061062144 Metadata: IndexId = 2
Metadata: ObjectId = 1463676262 m_prevPage = (0:0) m_nextPage = (0:0)
pminlen = 13 m_slotCnt = 2 m_freeCnt = 8066
m_freeData = 135 m_reservedCnt = 0 m_lsn = (3046:350:12)
m_xactReserved = 0 m_xdesId = (0:11665608) m_ghostRecCnt = 0
m_tornBits = 0 Allocation Status GAM (1:2) = ALLOCATED SGAM (1:3) = ALLOCATED
PFS (1:8088) = 0x60 MIXED_EXT ALLOCATED 0_PCT_FULL DIFF (1:6) = CHANGED
ML (1:7) = NOT MIN_LOGGED DATA: Slot 0, Offset 0x7a, Length 13, DumpStyle BYTE Record Type = INDEX_RECORD Record Attributes =
Memory Dump @0x0849C07A 00000000: 06010000 00b52000 00010000 00††††††††...... ...... Slot 1, Offset 0x6d, Length 13, DumpStyle BYTE Record Type = INDEX_RECORD Record Attributes =
Memory Dump @0x0849C06D 00000000: 06020000 00b52000 00010001 00††††††††...... ...... OFFSET TABLE: Row - Offset
1 (0x1) - 109 (0x6d)
0 (0x0) - 122 (0x7a) DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

我们删除id=1的记录
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRAN
DELETE FROM testghostindexnoncluster WHERE [id]=1
--ROLLBACK TRAN
再看一下索引页面
DBCC TRACEON(3604,-1)
GO
DBCC PAGE([pratice],1,15663,1) --索引页
GO

DATA: Slot 0, Offset 0x7a, Length 13, DumpStyle BYTE Record Type = GHOST_INDEX_RECORD Record Attributes =
Memory Dump @0x0849C07A 00000000: 0a010000 00b52000 00010000 00††††††††...... ...... Slot 1, Offset 0x6d, Length 13, DumpStyle BYTE Record Type = INDEX_RECORD Record Attributes =
Memory Dump @0x0849C06D 00000000: 06020000 00b52000 00010001 00††††††††...... ...... OFFSET TABLE: Row - Offset
1 (0x1) - 109 (0x6d)
0 (0x0) - 122 (0x7a) DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

可以看到第一行记录被标记为Record Type = GHOST_INDEX_RECORD
我们回滚事务
ROLLBACK TRAN
恢复正常了,索引页面中第一行记录的Record Type = INDEX_RECORD
DATA: Slot 0, Offset 0x94, Length 13, DumpStyle BYTE Record Type = INDEX_RECORD Record Attributes =
Memory Dump @0x0849C094 00000000: 06010000 00b52000 00010000 00††††††††...... ...... Slot 1, Offset 0x6d, Length 13, DumpStyle BYTE Record Type = INDEX_RECORD Record Attributes =
Memory Dump @0x0849C06D 00000000: 06020000 00b52000 00010001 00††††††††...... ...... OFFSET TABLE: Row - Offset
1 (0x1) - 109 (0x6d)
0 (0x0) - 148 (0x94) DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
DROP TABLE testghostindexnoncluster
GO
如有不对的地方,欢迎大家拍砖o(∩_∩)o
SQLSERVER中的鬼影索引的更多相关文章
- SQLSERVER中如何忽略索引提示
SQLSERVER中如何忽略索引提示 当我们想让某条查询语句利用某个索引的时候,我们一般会在查询语句里加索引提示,就像这样 当在生产环境里面,由于这个索引提示的原因,优化器一般不会再去考虑其他的索引, ...
- SQLServer中重建聚集索引之后会影响到非聚集索引的索引碎片吗
本文出处:http://www.cnblogs.com/wy123/p/7650215.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
- 在SQLSERVER中创建聚集索引
CREATE CLUSTERED INDEX CLUSTER_id ON TABLE_name(ID)------批量
- SQLServer中间接实现函数索引或者Hash索引
本文出处:http://www.cnblogs.com/wy123/p/6617700.html SQLServer中没有函数索引,在某些场景下查询的时候要根据字段的某一部分做查询或者经过某种计算之后 ...
- 解决“动软代码生成器在SqlServer中会将唯一索引识别为主键"的Bug
动软代码生成器在SqlServer中,生成的代码会将唯一索引错误地识别为主键, 反编译源代码后,发现其中的SQL条件有误,现修复此Bug. 修复方法:将附件中的”Maticsoft.DbObjects ...
- SQLServer中在视图上使用索引(转载)
在SQL Server中,视图是一个保存的T-SQL查询.视图定义由SQL Server保存,以便它能够用作一个虚拟表来简化查询,并给基表增加另一层安全.但是,它并不占用数据库的任何空间.实际上,在你 ...
- SQLServer中使用索引视图
在SQL Server中,视图是一个保存的T-SQL查询.视图定义由SQL Server保存,以便它能够用作一个虚拟表来简化查询,并给基表增加另一层安全.但是,它并不占用数据库的任何空间.实际上,在你 ...
- 我是如何在SQLServer中处理每天四亿三千万记录的
首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...
- C#批量插入数据到Sqlserver中的四种方式
我的新书ASP.NET MVC企业级实战预计明年2月份出版,感谢大家关注! 本篇,我将来讲解一下在Sqlserver中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的 ...
随机推荐
- StreamSets学习系列之StreamSets是什么?
不多说,直接上干货! StreamSets是一个侧重数据集成.数据加工流程构建的平台,也是一个开源的产品.通过StreamSets,用户可以方便的接入不同的数据源,并且完成数据加工流程的构建.Stea ...
- Gen对于break、continue与return的处理
void tryItOut () {} void wrapItUp () {} void tryFinally() { for (int i = 0; i < 2; i++) { try { t ...
- 什么是编程语言,什么是Python解释器
转自白月黑羽python在线教程:http://www.python3.vip/doc/blog/python/2018071401/ 0基础学Python之1:什么是编程语言,什么是Python解释 ...
- js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1
1. 前言 这两天看了一下TOM大叔的<深入理解js系列>中的基础部分,根据自己的实际情况,做了读书笔记,记录了部分容易绊脚的问题.写篇文章,供大家分享. 2. 关于HTMLCollect ...
- haproxy+keepalived原理特点
所有的系统,都是先经历一个单台机器搞所有业务的时代,一个程序+一个mysql数据库,就可以满足开发及第一个版本上线的要求.随着,数据的增加以及业务的增长,这些应用就面临一个访问量的扩大以及扩展的问题. ...
- 神经网络优化方法总结:SGD,Momentum,AdaGrad,RMSProp,Adam
1. SGD Batch Gradient Descent 在每一轮的训练过程中,Batch Gradient Descent算法用整个训练集的数据计算cost fuction的梯度,并用该梯度对模型 ...
- php里use关键字与class_alias的作用域区别
use可以用在命名空间下,也可以不用再命名空间下,他在两者中的作用是一致的,都是在编译的时候执行,不真正的加载类,因为是编译的时候执行,所以只能在全局环境使用,及不能使用在方法内部,条件判断内部. 引 ...
- 数组filter()参数详解,巧用filter()数组去重
数组方法挺多,但是用来用去可能也就foreach,splice以及slice接触较多,filter()说实话之前也没过多了解.其实filter()为数组提供过滤功能,它会遍历数组所有元素,并返回满足条 ...
- nodejs遇到的问题
1.express-session deprecated undefined resave option; provide resave option app.js:49:9 express-sess ...
- 文档数据库MongoDB
MongoDB是一个基于分布式文件存储的文档式数据库.其由C++编写, 旨在为Web应用提供可扩展的高性能数据存储解决方案. MongoDB中每条数据记录被作为一个文档存储,文档由集合(collect ...