索引初探(三)

索引初探(三)

由于前一篇写的有点匆忙很多地方不是很简单,这一片再描述一些概念和细节。

首先,我们都知道在数据库中的存储分为两种结构,一是堆;二是B树。堆的数据是没有排序也就没有结构性可言,我们可以简单理解为没有索引的表数据就是以堆的形式存在的。与之相对的,索引都是B树的形式存储,这样的话索引中数据是有序排列的。

其次,索引的结构上篇也是讲了,我们这里再根据非聚集索引的结构来对比一下聚集索引。

如图(官方提供的非聚集索引的结构图):

201112221218205094

我们不难看出,上面红色标注的是非聚集索引,下面是聚集索引或者堆。由这个图来分析:

1.非聚集索引与聚集索引一样都是B树结构。

2.非聚集索引的叶子节点不是数据页,这样非聚集索引的叶子节点只包含键值和定位符(定位符,存在两种可能,如果表中有了聚集索引那么定位符就是个直接指向数据所在行的物理指针,如果有聚集索引,那么就是一个指向索引的聚集键)

3.与聚集索引不同,非聚集索引本身并不会改变数据页的存储模式。

本篇的重点:非聚集索引

非聚集索引包含了索引键列,包含列和书签。书签的值根据所在表是堆还是聚集索引既可以是RID也可以是聚集索引键,我们用两个图对比看一下一目了然。

12035107-af13455db92446758c7c03ada6c759f6

上图显示的是非聚集索引在对上的实际结构,可以发现除了索引键值外,就是“RID”就是指向数据页的指针。

12040305-1618ad7dbaa04516ab10b0513f52b9dd

上图是非聚集索引在聚集索引上的结构,可以发现除去索引键值外,就是聚集索引键,查询数据时继续到索引中去寻找数据。

那么非聚集索引的优点:

1、因为在SQL Server中一页只是8K,页面空间有限,所以一行所包含的列数越少,它能保存的行就越多。非聚集索引通常不包含表中所有的列,它一般只包含非常少数的列。因此,一个页上将能包含比表行(所有的列)更多行的非聚集索引。

2、非聚集索引的另一个好处是,它有一个独立于数据表的结构,所以可以被放置在不同的文件组,使用不同的I/O路径,这意味着SQL Server可以并行访问索引和表,使查找更快速。

3、与聚集索引不同的时,一个表中可以有多个非聚集索引增加查询覆盖和交叉等等可以提高查询速度。

通过对聚集和非聚集索引的描述大概了解两种索引的基本结构和优缺点,下面根据其他人总结的什么情况下建立何种索引的一个常规方式:

                           使用聚集索引      使用非聚集索引
外键列                          应                      应
主键列                          应                      应
列经常被分组排序             应                     应
返回某范围内的数据          应                   不应
小数目的不同值               应                    不应
大数目的不同值               不应                   应
频繁更新的列                 不应                    应
频繁修改索引列              不应                    应
一个或极少不同值           不应                    应

总结:

      通过对索引的介绍和测试,我们发现索引能大幅提高查询的效率,但是同样相应的维护成本和性能消耗也是非常大的,这需要我们根据实际情况进行合理的设计。 当一个查询被传到数据引擎时,SQL Server可以通过三种路径获取数据来满足这个查询。

  1.     不需要访问表仅需要访问索引本身,这种情况必须是索引覆盖了请求所包含的列
  2.     使用索引键值去访问非聚集索引,然后使用书签访问非聚集索引所在表
  3.     全表扫描来获取数据

    了解这些基础概念接下来我们将从实际应用中去解决如何优化、如何合理化使用索引。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119753.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • jsonfield注解不生效(write javabean error fastjson)

    @jsonfield看源码它可以作用于字段和方法上。引用网上说的,一、作用field@jsonfield作用在field时,其name不仅定义了输入key的名称,同时也定义了输出的名称。但是我在使用中,发现并不如上所说。例如@jsonfield(name=”project_id”)privatelongprojectid发现bean转json的时候并是”project_id”:xxx的形式,…

    2022年4月17日
    63
  • pagecontext request session_pagecontent

    pagecontext request session_pagecontent ${pageContext.request.contextPath}是JSP取得绝对路径的方法,等价于<%=request.getContextPath()%> 。 也就是取出部署的应用程序名或者是当前的项目名称 比如我的项目名称是demo1在浏览器中输入为http://localhost:8080/demo1/a.jsp${pageContext.request.co…

    2022年9月17日
    0
  • pytest的使用_java中方法的调用

    pytest的使用_java中方法的调用Pytest执行用例规则Pytest在命令行中支持多种方式来运行和选择测试用例1.对某个目录下所有的用例pytest2.对模块中进行测试pytesttest_mod.py3.对文件夹进行

    2022年7月30日
    3
  • vim 搜索字符串_python查找字符串位置

    vim 搜索字符串_python查找字符串位置搜索(查找)#搜索模式/ #前向搜索匹配? #反向搜索匹配#移动定位n #跳到下一个匹配的位置N #跳到上一个匹配的位置* #对光标当前所在的完整单词进行前向搜索匹配# #对光标当前所在的完整单词进行后向搜索匹配g*#前向搜索光标当前所在单词g##反向搜索光标当前所在单词搜索时字母大小写情况设置#设置vimrc文件#当输入的搜索词全部是小写时,忽略大小写;搜索词至少有一个大写字母时,进行大小写匹配搜索setignorecase

    2022年9月23日
    0
  • redis HSCAN命令及jedis的hscan方法[通俗易懂]

    redis HSCAN命令及jedis的hscan方法[通俗易懂]参考文档:http://doc.redisfans.com/key/scan.html@Override publicScanResultshscanToResltByVague(Stringkey,Stringpattern,Stringcursor,intpageSize){ List<Map.Entry<String,String>>result=null; List<Map.Entry<String,String&

    2022年10月31日
    0
  • String字符串截取几种方法

    String字符串截取几种方法String截取字符串publicstaticvoidmain(String[]args){ Stringa="abcd-efg"; Stringa1=a.substring(a.lastIndexOf("-")+1); Stringa2=a.substring(0,a.indexOf("-")); System.out.println(a1);//efg …

    2022年5月19日
    51

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号