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中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的 ...
随机推荐
- JavaScript -- FileSystemObject
-----056-FileSystemObject.html----- <!DOCTYPE html> <html> <head> <meta http-eq ...
- JavaScript -- Window-Name
-----027-Window-Name.html----- <!DOCTYPE html> <html> <head> <meta http-equiv=& ...
- 高可用的MongoDB集群-实战篇
1.概述 最近有同学和网友私信我,问我MongoDB方面的问题:这里我整理一篇博客来赘述下MongoDB供大家学习参考,博客的目录内容如下: 基本操作 CRUD MapReduce 本篇文章是基于Mo ...
- 23-hadoop-hive的DDL和DML操作
跟mysql类似, hive也有 DDL, 和 DML操作 数据类型: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ ...
- centos7 安装配置postgresql
考:https://www.linuxidc.com/Linux/2017-10/147536.htm http://blog.51cto.com/12482328/2090844 https://w ...
- php还原16进制特殊字符
特殊字符的16进制表:https://websitebuilders.com/tools/html-codes/ascii/ 可以通过 hexdec() 和 chr()方法来进行转换, 例子: < ...
- apk的php解析
<?php/****************************************************** * Android APK File Parser * Author: ...
- 记一次java程序占用cpu超高排查
1.首先通过top命令查看占用cpu过高的pid #top top - 18:07:25 up 48 days, 1:07, 3 users, load average: 11.94, 11.9 ...
- [转]Bootstrap table 分页 In asp.net MVC
本文转自:https://www.cnblogs.com/lenovo_tiger_love/p/7474403.html 中文翻译文档: http://blog.csdn.net/rickiyeat ...
- 表格列mouse经过时高亮显示
前几天Insus.NET有练习<表格行mouse经过时高亮显示>http://www.cnblogs.com/insus/p/3715733.html ,今天有奇想,是否可以实现mouse ...