我们都知道建索引是需要谨慎的,当只有利大于弊的时候才适合建,同时也知道建索引是需要维护成本的,这个维护也就在于DML操作,下面具体看看到底DML对索引都有哪些内幕。。。。

一:delete操作

现在大家都已经知道索引是以B树的形式存在,既然是B树就要给大家展示一下叶子节点和分支结点,先准备点测试数据,如下代码:


CREATE TABLE Person(ID INT,NAME CHAR(200))
CREATE INDEX idx_Name ON Person(NAME)DECLARE @ch AS INT=65
WHILE @ch<=122
BEGININSERT INTO dbo.Person(ID,NAME)VALUES(@ch,REPLICATE(CHAR(@ch),200))SET @ch=@ch+1
END

1. 叶子结点的变化

从上面的图中大概可以看到,当我插入完毕后,4个索引数据页就出来了,其中PID=200的为分支数据页,其他三个为叶子节点数据页,编号分别为175,201,202,然后我就挑选第二个叶子节点数据页201号,看看里面的数据是啥样的。

从数据页中可以看到在201号数据页中有18个槽位,当然除了通过槽位看记录条数之外,你还可以通过Pageheader中的m_slotCnt来观察记 录个数,如下图:

接下来,大家再看看slot0槽位的内容是啥样,如下代码:


0000000000000000:   16484848 48484848 48484848 48484848 †.HHHHHHHHHHHHHHH
0000000000000010:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000020:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000030:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000040:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000050:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000060:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000070:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000080:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000090:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
00000000000000A0:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
00000000000000B0:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
00000000000000C0:   48484848 48484848 48970000 00010007 †HHHHHHHHH.......
00000000000000D0:   00020000 ††††††††††††††††††††††††††††....

看到内容之后,我们把这条记录删掉,然后快速的观察数据页的变化,很有意思的。。。。如下图:

仔细观察上面的图,你会看到m_slotCnt=18。。。。你也看到m_ghostRecCnt=1,看这个名字你就知道是“幻象”的意思。。。正因为被标记为幻象,是因为sqlserver的后台进程会在某个时候把数据正真的删除掉,比如你过个几秒之后再查看就能看到真的被清除了。

2. 分支节点的变化

说完叶子节点,然后我们继续看看分支节点,通过前面的博文,你应该知道在分支节点中是依次保存着排序后的每个叶子节点中的最小值,刚好 我删除了第二个叶子节点的第一个值,那这个值也正好保存在分支节点中,下面一个问题来了,我刚才删除了ID=72的记录,那这条记录还会在分支节点中保存吗???不用太兴奋,用数据说话,继续查看200号数据页。

可以看到分支节点是不会删除这条记录的。

二:insert操作

索引都是按照索引列升序的,当我insert的时候是不是需要给我插入到排序的指定位置呢???比如说我刚才删除的HHH。。。数据,这次我再insert的时候,是不是需要给我插入到第二个数据页的slot0位置呢???下面继续用数据说话。


INSERT INTO dbo.Person VALUES(72,REPLICATE(CHAR(72),200))
DBCC PAGE(Ctrip,1,201,1)Slot 0, Offset 0x101c, Length 212, DumpStyle BYTERecord Type = INDEX_RECORD           Record Attributes =  NULL_BITMAP     Record Size = 212Memory Dump @0x000000000FE5B01C0000000000000000:   16686868 68686868 68686868 68686868 †.hhhhhhhhhhhhhhh
0000000000000010:   68686868 68686868 68686868 68686868 †hhhhhhhhhhhhhhhh
0000000000000020:   68686868 68686868 68686868 68686868 †hhhhhhhhhhhhhhhh
0000000000000030:   68686868 68686868 68686868 68686868 †hhhhhhhhhhhhhhhh
0000000000000040:   68686868 68686868 68686868 68686868 †hhhhhhhhhhhhhhhh
0000000000000050:   68686868 68686868 68686868 68686868 †hhhhhhhhhhhhhhhh
0000000000000060:   68686868 68686868 68686868 68686868 †hhhhhhhhhhhhhhhh
0000000000000070:   68686868 68686868 68686868 68686868 †hhhhhhhhhhhhhhhh
0000000000000080:   68686868 68686868 68686868 68686868 †hhhhhhhhhhhhhhhh
0000000000000090:   68686868 68686868 68686868 68686868 †hhhhhhhhhhhhhhhh
00000000000000A0:   68686868 68686868 68686868 68686868 †hhhhhhhhhhhhhhhh
00000000000000B0:   68686868 68686868 68686868 68686868 †hhhhhhhhhhhhhhhh
00000000000000C0:   68686868 68686868 68c10000 00010002 †hhhhhhhhh.......
00000000000000D0:   00020000 ††††††††††††††††††††††††††††....Slot 1, Offset 0x1f04, Length 212, DumpStyle BYTERecord Type = INDEX_RECORD           Record Attributes =  NULL_BITMAP     Record Size = 212Memory Dump @0x000000000FE5BF040000000000000000:   16484848 48484848 48484848 48484848 †.HHHHHHHHHHHHHHH
0000000000000010:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000020:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000030:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000040:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000050:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000060:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000070:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000080:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
0000000000000090:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
00000000000000A0:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
00000000000000B0:   48484848 48484848 48484848 48484848 †HHHHHHHHHHHHHHHH
00000000000000C0:   48484848 48484848 48c10000 00010015 †HHHHHHHHH.......
00000000000000D0:   00020000 ††††††††††††††††††††††††††††....

从上面可以看到,当我再次把删除的”H"插入到数据页的时候,发现“H”在201号数据页的slot1位置了,有人就奇怪了,,,为什么不在slot0 的???

仔细想想确实是这么一个道理,那就是sql是不区别大小写的,“H”和“h”对sqlserver来说都是一样,这里还有一个问题就是数据页分裂,比如说当你insert的数据页已满,那这时候该怎么办呢?sqlserver的手段就是数据页分裂,将满页的一半数据导出到新分配的数据页,同样我也可以做个例子。


CREATE TABLE Person(ID INT,NAME CHAR(5) DEFAULT 'xxxxx')
CREATE INDEX idx_Name ON Person(NAME)DECLARE @i as int=1
WHILE @i<801
BEGININSERT INTO dbo.Person(ID) VALUES(@i)SET @i=@i+1
END

接下来,我导出126号数据页的记录,可以看到它的范围是1-449,如下图:

下面我要做的事情就是插入一个ID在1-449范围的一条记录,这样的话就会造成数据页分裂了,对不对。

可以看到,现在多了一个192号数据页,是不是很有意思,哈哈~~ 然后我就非常好奇的再次导出126,192号数据页,看看数据是不是只剩 一半啦~~~

三:update操作

如果你看懂了上面的insert和delete,那么update就是这两个操作的组合,也没什么好说的。

好了,夜深了,洗洗睡了~


如您有更多问题与我互动,扫描下方进来吧~

Sql Server之旅——第九站 看看DML操作对索引的影响相关推荐

  1. Sql Server之旅——第一站 那些给我们带来福利的系统视图

    本来想这个系列写点什么好呢,后来想想大家作为程序员,用的最多的莫过于数据库了,但是事实上很多像我这样工作在一线的码农,对sql 都一知半解,别谈优化和对数据库底层的认识了,我也是这样... 一:那些系 ...

  2. Sql Server之旅——第二站 理解讨厌的表扫描

    很久以前我们在写sql的时候,最怕的一件事情就是sql莫名奇妙的超级慢,慢的是几根烟抽完,那个小球还在一直转...这个着急也只有当事人才明白,后来听说有个什么"评估执行计划",后来 ...

  3. Sql Server之旅——第二站 理解万恶的表扫描

    很久以前我们在写sql的时候,最怕的一件事情就是sql莫名奇妙的超级慢,慢的是撸一管子回来,那个小球还在一直转...这个着急也只有当事人才 明白,后来听说有个什么"评估执行计划", ...

  4. Sql Server之旅——第十一站 简单说说sqlserver的执行计划

    原文:Sql Server之旅--第十一站 简单说说sqlserver的执行计划 我们知道sql在底层的执行给我们上层人员开了一个窗口,那就是执行计划,有了执行计划之后,我们就清楚了那些烂sql是怎么 ...

  5. Sql Server之旅——第五站 确实不得不说的DBCC命令

    Sql Server之旅--第五站 确实不得不说的DBCC命令 原文:Sql Server之旅--第五站 确实不得不说的DBCC命令 今天研发中心办年会,晚上就是各自部门聚餐了,我个人喜欢喝干红,在干 ...

  6. Sql Server之旅——第十二站 sqltext的参数化处理

    Sql Server之旅--第十二站 sqltext的参数化处理 原文:Sql Server之旅--第十二站 sqltext的参数化处理 说到sql的参数化处理,我也是醉了,因为sql引擎真的是一个无 ...

  7. 如何处理SQL Server事务复制中的大事务操作

    如何处理SQL Server事务复制中的大事务操作 事务复制的工作机制 事务复制是由 SQL Server 快照代理.日志读取器代理和分发代理实现的.快照代理准备快照文件(其中包含了已发布表和数据库对 ...

  8. sql连接显示未能连接服务器,SQL Server 2008无法连接到服务器的操作教程

    这篇文章为各位带来的内容是SQL Server 2008无法连接到服务器相关的,对此感兴趣的用户可以去下文看看无法连接到服务器的具体操作流程. SQL Server 2008无法连接到服务器的操作教程 ...

  9. Sql Server之旅——第十二站 对锁的初步认识

    作为一个开发人员,锁机制也是我们程序员必须掌握的东西,很久之前在学习锁的时候,都是教科书上怎么说,然后我怎么背,缺少一个工具让我们眼见为实...如果这样的话,学习一个东西就很容易忘记...因为这些都是 ...

最新文章

  1. PCLPCL/OpenNI tutorial 2: Cloud processing (basic)
  2. 毫米波雷达基本技术与应用
  3. 谈谈我对Manacher算法的理解
  4. 防止用户利用PHP代码DOS造成用光网络带宽
  5. c++中内敛函数_C++ 内联函数 | 菜鸟教程
  6. boost::geometry::strategy::distance::haversine用法的测试程序
  7. 《数据库SQL实战》从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。 注意对于重复的emp_no进行忽略。
  8. python文件可以包括任何数据内容_python 文件数据合并(数据行不对应)?
  9. 家长必读:不想逼孩子,你应该这样做
  10. Apache网站服务
  11. C++笔记-Stack around the variable问题解析
  12. 【神经网络】LSTM理论介绍
  13. matlab如何打开word文档,matlab操作word
  14. C++ delete释放内存的本质
  15. CSS“隐藏”元素的几种方法的对比
  16. 这次,大数据工程师赢了!
  17. 【前端监控系统】埋点数据上报的3种方式
  18. c语言输出菱形for循环_c语言输出菱形
  19. 包邮赠书!李航《统计学习方法》详解
  20. 业务还是技术测试?从初级软件测试到高级测试工程师,我都经历了什么......

热门文章

  1. 公众平台关注用户达到5万即可开通流量主功能 可以推广APP应用
  2. Android 使用XmlPullParser解析xml
  3. Wave 文件(5): 获取 Wave 文件的格式信息
  4. 最大连续子数组和与JUnit测试
  5. Amazon Alexa 新里程碑: 50000 个功能、 20000 种设备、 3500 个品牌
  6. 有序的Map集合--LinkedHashMap
  7. 大数据服务社会的一个有益实践
  8. 阿里云欧洲数据中心开放运营:与沃达丰达成战略合作
  9. Briefly unavailable for scheduled maintenance message after doing automatic upgrade
  10. .NET WinForm程序中给DataGridView表头添加下拉列表实现数据过滤