我们在学sqlserver的时候,大多教科书和前辈们都说状态少的字段不要建索引,由此带来的开销还不如不建索引,但是这句话有多少人真的知道,或者说有多少人真的对此有比较深刻的理解,而不是听别人道听途说。。。这样记得快,忘记的也不慢。。。这篇我来分析一下这句话到底有几个意思。

一:现象

首先我们还是用测试数据来发现问题,我先建立一个Person,有5个字段,建表sql如下:

DROP TABLE dbo.Person

CREATE TABLE Person(ID INT PRIMARY KEY IDENTITY,NAME VARCHAR(900),Age INT,Email VARCHAR(20),isMan INT )

-- 在isMan字段创建非聚集索引(0:女 1:男)CREATE INDEX idx_isMan ON dbo.Person(isMan)

DECLARE @ch AS INT=0

WHILE @ch<=100000BEGININSERT INTO dbo.Person(NAME,Age,Email,isMan)VALUES    (REPLICATE(CHAR(@ch),50),      @ch,CAST(CAST(RAND()*1000000000 AS INT) AS VARCHAR(10))+'qq.com',      @ch%2    )SET @ch=@ch+1END

通过上面的sql发现ID为聚集索引,isMan为非聚集索引,isMan也就是两种状态(0,1),并且插入10w条记录,截图如下:

sql都做完了,接下来要做的事情就是查询下:isMan=1的记录,如下图:

我靠。。。我明明是在isMan上做数据检索的,怎么就变成 “聚集索引扫描”了???这sqlserver什么意思嘛,居然不走我的“idx_isMan”索引,却走他的“聚集索引(PKPerson3214EC276EF57B66)”。。。。同时也看到上面的”逻辑读取”为521。。。说明在内存中走了521个数据页。但是我不服呀。。。我一定要让执行计划走我的索引。。。办法就是强制指定。。。如下图。

看到上面的图,你是不是已经疯了。。。我才捞5w的数据,你给我走了10w多次数据页。。。这么说1条记录要走两个数据页。。。而扫描聚集索引才走521个数据页,相差200倍。。。难怪执行计划打死也不走“idx_isMan”这条索引。。。

二:分析原因

现在很生气,整个人都不好了,为什么会这样???为了找出问题,我们还得看数据页。

DBCC TRACEON(3604,2588)DBCC IND(Ctrip,Person,-1)

通过上面的三个图,大概可以看到,10w条数据用了697数据页,其中聚集索引有521个,非聚集索引为176个,这也说明了上面的”聚集索引扫描“走遍了它自己所有的数据页来才捞出数据,同时还发现这两个索引都有一个共同特征就是,只有一个根节点(indexLevel=1)和无数个(indexLevel=0)叶子节点,然后我脑子里面就有一幅图出来了。。。

上面就是我构思出来的图,这个专业一点的名字叫做书签查找。。。我们通过建立”idx_isMan“索引后,就会构建右半图的B树结构,其中索引记录会存放两个值,一个是索引值isMan和一个聚集索引值ID,如果你不相信的话,可以通过DBCC Page去探索"idx_isMan"的索引页,你也可以通过DBCC SHOW_STATISTICS 去查看,如图:

然后引擎通过“idx_isMan“扫描后,拿到了key值,但是非常可惜,我是select * 的,所以必须还要喷出记录中的Name,Emai等l字段,但是”index_isMan"中并没有保存这几个字段,所以必须通过key去”聚集索引“的B树中去找。。。最后通过”聚集索引“的B树找到了目标记录,这也就是所谓的执行计划中的”键查找“,然后喷出”Name,Email“等字段。。。。问题就在这里。。。因为我这样来回的蹦跶蹦跶。。。造成了找出完整的一个记录,需要蹦跶2-3次数据页。。。具体的寻找记录,可参考图中的”紫色线条“,最后也就造成了10w多次蹦跶。。。

三:启示

那这个例子给我们什么启示呢???仔细想想你就知道。。。使用非聚集索引,千万不要捞取过多的数据。。。因为过多的数据会造成在多个B树中来回的蹦跶。。。想要做到捞取数据较少,就必须在高唯一性的字段上建立索引,这样的话在非聚集索引B树中符合的数据相对较少,也就减少了我蹦跶到”主键索引“的B树次数。。。这样的话来回蹦跶的次数远远比”聚集索引“扫描来的实惠,对不对。。。

四:结论

必须在唯一性较高的字段上建立非聚集索引。

sqlserver怎么查看索引_Sql Server之旅——第六站 为什么都说状态少的字段不能建索引...相关推荐

  1. Sql Server之旅——第六站 为什么都说状态少的字段不能建索引

    我们在学sqlserver的时候,大多教科书和前辈们都说状态少的字段不要建索引,由此带来的开销还不如不建索引,但是这句话有多少人真的知道,或者说有多少人真的对此有比较深刻的理解,而不是听别人道听途说. ...

  2. Sql Server之旅——第八站 看公司这些DBA们设计的这些复合索引

    这一篇再说下索引的最后一个主题,索引覆盖,当然学习比较好的捷径是看看那些大师们设计的索引,看从中能提取些什么营养的东西,下面我们看看数据库中一个核心的Orders表. 一:查看表的架构 1. 先查看这 ...

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

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

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

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

  5. 为什么重复值高的字段不能建索引(比如性别字段等)

    结论(以innodb为例) a.非聚簇索引存储了对主键的引用,如果select字段不在非聚簇索引内,就需要跳到主键索引(上图中从右边的索引树跳到左边的索引树),再获取select字段值 b.如果非聚簇 ...

  6. 数据索引是什么?索引作用是什么?什么样的字段适合建索引?索引的优缺点是什么?

    数据索引是什么?索引作用是什么?什么样的字段适合建索引?索引的优缺点是什么? 数据库索引,是数据库管理系统中一个排序的数据结构,索引的实现通常使用B树及其变种B+树.在数据之外,数据库系统还维护着满足 ...

  7. mysql 重复率高字段 索引,为什么重复值高的字段不能建索引(+聚集索引和非聚集索引)...

    ?一.原因: -?非聚簇索引存储了对主键的引用,如果?select?字段不在非聚簇索引内,就需要跳到主键索引. -?如果非聚簇索引值重复率高,那么查询时就会大量出现上图中从右边跳到左边的情况,导致整个 ...

  8. sqlserver查看索引_SQL Server页中行物理存储

    SQL Server页有很多类型: 1 – 数据页. 记录堆或者聚集索引叶子级的数据 2 – 索引页. 用于保存聚集索引中的中间页和根页,或者非聚集索引的所有页 3 – text mix page. ...

  9. sql分区表上创建索引_SQL Server中分区表和索引的选项

    sql分区表上创建索引 介绍 (Introduction) I work for a large, multinational financial institution. Like most com ...

最新文章

  1. linux——关于ip、静态网络、动态网络、网关、DNS的设置
  2. HarmonyOS之变量可视化调试
  3. 万字长文 | 漫谈libco协程设计及实现
  4. 程序员们记得还是八五年PC登陆我国时候的事?
  5. 9名程序员被抓!这次我并不同情他们!
  6. 在碎片化阅读充斥眼球的时代,要高效读论文
  7. pythonjson实例_python对json的相关操作实例详解
  8. bzoj2599 [IOI2011]Race
  9. 医院耗材管理系统开发_8
  10. webstorm主题设置
  11. 前端JS-页面延迟刷新
  12. Windows程式开发设计指南--开始
  13. oracle实用教程选择题,第3章 表与表数据操作 Oracle实用教程(第3版)PPT.ppt
  14. 391、Java框架46 -【Hibernate - 查询HQL、查询Criteria、查询标准SQL】 2020.10.19
  15. (一)PBR材质理论
  16. 红孩儿网狐Cocos经典棋牌开发教程-卞安-专题视频课程
  17. 金融风险管理基本框架
  18. Win系统蓝牙设备删除失败 - 解决方案
  19. Reflected Cross Site Scripting (XSS)
  20. 3.对互斥事件和条件概率的相互理解《zobol的考研概率论教程》

热门文章

  1. Java算法之 一致性hash算法原理及实现
  2. DevExpress的DateEdit设置显示日期和时间
  3. linux命令:系统裁剪之五dropbear嵌入式系统专用ssh服务
  4. 润乾集算报表提升性能之可控缓存
  5. [转载] 中华典故故事(孙刚)——08 狗咬吕洞宾
  6. 更改sybase下设备名
  7. RichTextBox实现关键字自定义颜色显示(C#)
  8. 线程或进程绑定到特定的cpu
  9. 当谈论设备指纹时,我们到底在说什么?(转)
  10. python操作excel表格文件--使用xlrd模块