索引结构

索引的类型

主存储格式 索引类型
基于磁盘的行存储 聚集、非聚集、唯一、Filtered
列存储 聚集列存储、非聚集列存储
内存优化 哈希、内存优化非聚集

行存储

行存储是存储关系表数据的传统方法。 “行存储”是指基础数据存储格式为堆、B+ 树(聚集索引)或内存优化表的表。 “基于磁盘的行存储”排除了内存优化表。

行存储索引

一般给表中的某个字段添加索引,使用的是基于磁盘的行存储索引。
对于行存储索引,这些键以树结构(B+ 树)存储。
它是按顺序排列的值列表,每个值都有指向这些值所在的数据页面的指针。
索引本身存储在页上,称为索引页。

索引设计注意事项

  • 对表编制大量索引会影响 INSERT、UPDATE、DELETE 和 MERGE 语句的性能,因为当表中的数据更改时,所有索引都须适当调整。 例如,如果在多个索引中使用了某个列,并且执行了修改该列数据的 UPDATE 语句,则必须更新包含该列的每个索引以及基础的基表(堆或聚集索引)中的该列。

    • 避免对经常更新的表进行过多的索引,并且索引应保持较窄,就是说,列要尽可能少。
    • 使用多个索引可以提高更新少而数据量大的查询的性能。 大量索引可以提高不修改数据的查询(例如 SELECT 语句)的性能,因为查询优化器有更多的索引可供选择,从而可以确定最快的访问方法。
  • 对小表进行索引可能不会产生优化效果,因为查询优化器在遍历用于搜索数据的索引时,花费的时间可能比执行简单的表扫描还长。 因此,小表的索引可能从来不用,但仍必须在表中的数据更改时进行维护。

  • 对于聚集索引,请保持较短的索引键长度。 另外,对唯一列或非空列创建聚集索引可以使聚集索引获益。

  • 无法指定 ntext、 text、 image、 varchar(max) 、 nvarchar(max)、
    varbinary(max) 数据类型的列为索引键列。

  • 在列中检查数据分布。 通常情况下,为包含很少唯一值的列创建索引或在这样的列上执行联接将导致长时间运行的查询。例如:‘性别’只有男和女两种

  • 如果索引包含多个列,则应考虑列的顺序。 在 WHERE 子句中使用的列等于 (=) ,大于 () ,小于 < (>) ,或 BETWEEN 搜索条件或参与联接,应首先放置。

  • 考虑对计算列进行索引。

聚集索引

行存储索引是按 B+ 树结构组织的。 索引 B+ 树中的每一页称为一个索引节点。 B+ 树的顶端节点称为根节点。 索引中的底层节点称为叶节点。 根节点与叶节点之间的任何索引级别统称为中间级。 在聚集索引中,叶节点包含基础表的数据页。 根节点和中间级节点包含存有索引行的索引页。 每个索引行包含一个键值和一个指针,该指针指向 B+ 树上的某一中间级页或叶级索引中的某个数据行。 每级索引中的页均被链接在双向链接列表中。

聚集索引在 sys.partitions中有一行,其中,索引使用的每个分区的 index_id = 1。 默认情况下,聚集索引有单个分区。 当聚集索引有多个分区时,每个分区都有一个包含该特定分区相关数据的 B+ 树结构。 例如,如果聚集索引有四个分区,就有四个 B+ 树结构,每个分区中有一个 B+ 树结构。

根据聚集索引中的数据类型,每个聚集索引结构将有一个或多个分配单元,将在这些单元中存储和管理特定分区的相关数据。 每个聚集索引的每个分区中至少有一个 IN_ROW_DATA 分配单元。 如果聚集索引包含大型对象 (LOB) 列,则它的每个分区中还会有一个 LOB_DATA 分配单元。 如果聚集索引包含的变量长度列超过 8,060 字节的行大小限制,则它的每个分区中还会有一个 ROW_OVERFLOW_DATA 分配单元。

数据链内的页和行将按聚集索引键值进行排序。 所有插入操作都在所插入行中的键值与现有行中的排序顺序相匹配时执行。

下图显式了聚集索引单个分区中的结构。

聚集索引的使用场景

  • 使用运算符(如 BETWEEN,、>>=、<和 <=)返回值范围。
    使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行物理相邻。 例如,如果某个查询在一系列销售订单号间检索记录, SalesOrderNumber 列的聚集索引可快速定位包含起始销售订单号的行,然后检索表中所有连续的行,直到检索到最后的销售订单号。

  • 返回大型结果集。

  • 使用 JOIN 子句;一般情况下,使用该子句的是外键列。

  • 使用 ORDER BY 或 GROUP BY 子句。
    在 ORDER BY 或 GROUP BY 子句中指定的列的索引,可以使 数据库引擎 不必对数据进行排序,因为这些行已经排序。 这会有助于提升查询性能。

列注意事项

一般情况下,定义聚集索引键时使用的列越少越好。 考虑具有下列一个或多个属性的列:

  • 唯一或包含许多不重复的值。
    例如,雇员 ID 唯一地标识雇员。 EmployeeID 列的聚集索引或主键约束可提高基于雇员 ID 号搜索雇员信息的查询的性能。 另外,可对 LastName、 FirstName、 MiddleName 列创建聚集索引,因为经常以这种方式分组和查询雇员记录,而且这些列的组合还可提供高区分度。

    提示:如果没有另行指定,在创建主键约束时,数据库引擎会创建一个聚集索引来支持该约束。 虽然可使用 uniqueidentifier 来强制实施作为主键的唯一性,但它不是有效的聚集键。 如果使用 uniqueidentifier 作为主键,建议将其创建为非聚集索引,然后使用另一列(如 IDENTITY)创建聚集索引。

  • 按顺序被访问
    例如,产品 ID 唯一地标识 Production.Product 数据库的 AdventureWorks2019 表中的产品。 在其中指定顺序搜索的查询(如 WHERE ProductID BETWEEN 980 and 999)将从 ProductID的聚集索引受益。 这是因为行将按该键列的排序顺序存储。

  • 定义为 IDENTITY。

  • 经常用于对表中检索到的数据进行排序。

聚集索引不适用于具有下列属性的列:

  • 频繁更改的列
    这将导致整行移动,因为 数据库引擎 必须按物理顺序保留行中的数据值。 这一点要特别注意,因为在大容量事务处理系统中数据通常是可变的。

  • 宽键
    宽键是若干列或若干大型列的组合。 所有非聚集索引将聚集索引中的键值用作查找键。 为同一表定义的任何非聚集索引都将增大许多,这是因为非聚集索引项包含聚集键,同时也包含为此非聚集索引定义的键列。

非聚集索引设计

基于磁盘的行存储非聚集索引包含索引键值和指向表数据存储位置的行定位器。 可以对表或索引视图创建多个非聚集索引。 通常,设计非聚集索引是为改善经常使用的、没有建立聚集索引的查询的性能。

与使用书中索引的方式相似,查询优化器在搜索数据值时,先搜索非聚集索引以找到数据值在表中的位置,然后直接从该位置检索数据。 这使非聚集索引成为完全匹配查询的最佳选择,因为索引包含说明查询所搜索的数据值在表中的精确位置的项。 例如,为了从 HumanResources. Employee 表中查询向特定经理负责的所有雇员,查询优化器可能使用非聚集索引 IX_Employee_ManagerID;它以 ManagerID 作为其键列。 查询优化器能快速找出索引中与指定 ManagerID匹配的所有项。 每个索引项都指向表或聚集索引中准确的页和行,其中可以找到相应的数据。 在查询优化器在索引中找到所有项之后,它可以直接转到准确的页和行进行数据检索。

非聚集索引体系结构

基于磁盘的行存储非聚集索引与聚集索引具有相同的 B+ 树结构,它们之间的显著差别在于以下两点:

  • 基础表的数据行不按非聚集键的顺序排序和存储。
  • 非聚集索引的叶级别是由索引页而不是由数据页组成。 非聚集索引的叶级别的索引页包含键列以及包含列。
    非聚集索引行中的行定位器或是指向行的指针,或是行的聚集索引键,如下所述:

    • 如果表是堆(意味着该表没有聚集索引),则行定位器是指向行的指针。 该指针由文件标识符 (ID)、页码和页上的行数生成。 整个指针称为行 ID (RID)。
    • 如果表有聚集索引或索引视图上有聚集索引,则行定位器是行的聚集索引键。

二、谈谈对数据库中索引的理解相关推荐

  1. 面试题(一)- 谈谈你对数据库中索引的理解

    转载自<http://www.cnblogs.com/newpanderking/p/3781043.html> 1.首先要明白无名无实莫要用索引:因为数据中的记录很多,为了方便我们查找, ...

  2. 数据库中索引(index)介绍

    本文主要介绍数据库中索引(index)的相关知识. 1 概述 1.1 What 数据库中的索引(index),是数据库管理系统(DBMS)中的一个排序的数据结构,用于协助快速查询.更新数据库表中的数据 ...

  3. mysql怎么删除临时表里的数据_谈谈MySQL数据库中临时表的应用

    MySQL在很多情况下都会用到临时表总结一下什么时候会用到临时表 什么是临时表MySQL用于存储一些中间结果集的表临时表只在当前连接可见当关闭连接时Mysql会自动删除表并释放所有空间. 以下讨论的是 ...

  4. 谈谈对java中分层的理解_让我们谈谈网页设计中的卡片设计

    谈谈对java中分层的理解 "I want a card", this is the first demand point that the customer said in th ...

  5. 谈谈对数据库中ACID、CAP、BASE的认识

    2019独角兽企业重金招聘Python工程师标准>>> ACID.CAP.BASE的区别与联系 这得从关系型数据库关系型数据库(RDBMS)和非关系型数据库(NoSQL)说起. RD ...

  6. Sqlite数据库中索引的使用、索引的优缺点

    要使用索引对数据库的数据操作进行优化,那必须明确几个问题: 1.什么是索引 2.索引的原理 3.索引的优缺点 4.什么时候需要使用索引,如何使用 围绕这几个问题,来探究索引在数据库操作中所起到的作用. ...

  7. mysql的索引缺点_Sqlite数据库中索引的使用、索引的优缺点

    pptv网络电视2017V4.0.2.0035 官方最新版 类型:网络电视大小:31.6M语言:中文 评分:9.2 标签: 立即下载 要使用索引对数据库的数据操作进行优化,那必须明确几个问题: 1.什 ...

  8. Oracle数据库中索引的维护

    本文只讨论Oracle中最常见的索引,即是B-tree索引.本文中涉及的数据库版本是Oracle8i. 一. 查看系统表中的用户索引 在Oracle中,SYSTEM表是安装数据库时自动建立的,它包含数 ...

  9. oracle传date参数十二小时,Oracle数据库中 to_date()与24小时制表示法及mm分钟的显示...

    一.在使用Oracle的to_date函数来做日期转换时,时候也许会直接的采用"yyyy-MM-dd HH:mm:ss"的格式作为格式进行转换,但是在Oracle中会引起错误:&q ...

最新文章

  1. dubbo 部分 配置的关系-dubbo github 官方案例
  2. [k8s]k8s pod的4种网络模式最佳实战(externalIPs )
  3. Web性能测试需监控的IIS性能指标
  4. 数据表_事物码(Transaction Code)信息
  5. 服务器端发送邮件签名采用Data URI scheme包含图片
  6. 深入理解表单脚本系列第一篇——表单对象
  7. 论文浅尝 | 基于神经网络的知识推理
  8. Nexus 3.31.1 maven 私服 搭建篇 linux
  9. Linux多线程Pthread学习小结
  10. 单片机单口不可用或被占用_单片机为什么一直用C语言,不用其他编程语言?只有学过的知道...
  11. 【Cocos游戏实战】功夫小子第七课之游戏主功能场景逻辑功能和暂停功能场景的分析和实现...
  12. UVA 11859 Division Game[Nim游戏]
  13. Object C与 C/C++混合编程
  14. redis通过hscan导入大hash key
  15. 科幻小说《霜与火》 by 雷·布雷德伯里
  16. 各邮箱的邮件接收服务器和发送服务器
  17. Win10系统无法安装geforce game ready driver?
  18. [等保测评]Web应用防火墙WAF产品汇总
  19. 退耦电容原理--退藕电容的一般配置原则
  20. svn解决黄色感叹号

热门文章

  1. Android 开发摆脱数据线 - Android studio 无线调试App
  2. 柔性电子: Triboelectric Nanogenerator摩擦生电
  3. 编程小TIPS:使用函数式风格Either来编程
  4. Android UI系列之侧滑粘稠效果的实现
  5. nginx的DR模式
  6. 三春过后诸芳尽. 荼蘼
  7. ESP8266开发之旅 阿里云物联网平台篇④ LED智能灯控制系统(MQTTS客户端直连)
  8. postgresql mysql 源码安装_PostGreSQL12 源码安装与字符集修改 (一)
  9. python数据分析实战之超市零售分析
  10. 解决 SQLite报错:OperationalError: row value misused