数据库索引:

索引(index)是帮助MySQL高效获取数据的数据结构(有效),在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。简而言之:帮助MySQL高效的查询出数据的数据结构叫做索引。

索引的优势:

  1. 索引类似于书籍的目录,提高数据检索的效率,减少数据库IO的成本

  2. 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗

索引的劣势:

  1. 实际上索引也是一张表,存储在磁盘上,该表保存了主键与索引字段,并指向实体类的记录

  2. 虽然索引大大提高了查询的速度,但是降低了增删改的速度,对表进行update、insert、delete时,需要对索引文件进行更新

从四点讲述索引功能:

  1. 为什么要给表加上主键?

  2. 为什么加索引后会使查询变快?

  3. 为什么加索引后会使写入、修改、删除变慢?

  4. 什么情况下要同时在两个字段上建索引?

首先我们想要了解索引的原理我们需要清楚一种数据结构(平衡树)也就是b tree或者 b+ tree ,当然,
有的数据库也使用哈希桶作用索引的数据结构, 然而,主流的RDBMS(关系型数据库)都是把平衡树当做数据表默认的索引数据结构的

聚集索引与非聚集索引

我们平时建表的时候都会为表加上主键, 在某些关系数据库中, 如果建表时不指定主键,数据库会拒绝建表的语句执行。
如果定义了主键,InnoDB会自动使用主键来创建聚集索引。如果没有定义主键,InnoDB会选择一个唯一的非空索引代替主键。如果没有唯一的非空索引,InnoDB会隐式定义一个主键来作为聚集索引。)

MyISAM:

B+Tree叶节点存放的是数据记录的地址,在检索的时候,先找到索引对应的数据记录的地址,再根据地址读取相应的数据记录,这种查找方式被称为“非聚集索引”。

InnoDB:

它的主键索引是聚集索引,即主键和行记录放在同一个叶节点,找到了主键也就找到了行记录;而它的非主键索引,或者说是辅助索引,是非聚集索引,跟MyISAM引擎的非聚集索引不同的是,MyISAM叶节点保存的是地址,而InnoDB是主键,InnoDB非聚集索引的索引文件和数据文件分开存储,索引文件的叶节点只保存主键,在查找时,要先找到叶节点中的主键,再根据主键去主索引文件查找详细行记录;因此,在设计表的时候,主键字段不宜过长。

为什么要给表加上主键?

事实上, 一个加了主键的表,并不能被称之为「表」。
一个没加主键的表,它的数据无序的放置在磁盘存储器上,一行一行的排列的很整齐
如果给表上了主键,那么表在磁盘上的存储结构就由整齐排列的结构转变成了树状结构, 也就是上面说的「平衡树」结构
换句话说,就是整个表就变成了一个索引,是所谓的「聚集索引」。
这就是为什么一个表只能有一个主键,一个表只能有一个「聚集索引」,因为主键的作用就是把「表」的数据格式转换成「索引(平衡树)」的格式放置。

为什么加索引后会使查询变快?

其中树的所有结点(底部除外)的数据都是由主键字段中的数据构成,也就是通常我们指定主键的id字段。最下面部分是真正表中的数据。

假如我们执行一个SQL语句: select * from table where id = 1256;
首先根据索引定位到1256这个值所在的叶结点,然后再通过叶结点取到id等于1256的数据行。
这里不讲解平衡树的运行细节, 但是从上图能看出,树一共有三层, 从根节点至叶节点只需要经过三次查找就能得到结果。如下图

假如一张表有一亿条数据 ,需要查找其中某一条数据,按照常规逻辑, 一条一条的去匹配的话,
最坏的情况下需要匹配一亿次才能得到结果,用大O标记法就是O(n)最坏时间复杂度,这是无法接受的,而且这一亿条数据显然不能一次性读入内存供程序使用。
因此, 这一亿次匹配在不经缓存优化的情况下就是一亿次IO开销,以现在磁盘的IO能力和CPU的运算能力, 有可能需要几个月才能得出结果。
如果把这张表转换成平衡树结构(一棵非常茂盛和节点非常多的树),假设这棵树有10层,那么只需要10次IO开销就能查找到所需要的数据, 速度以指数级别提升。
n是记录总树,底数是树的分叉数,结果就是树的层次数。换言之,查找次数是以树的分叉数为底,记录总数的对数,用公式来表示就是

用程序来表示就是Math.Log(100000000,10),100000000是记录数,10是树的分叉数(真实环境下分叉数远不止10),
结果就是查找次数,这里的结果从亿降到了个位数。因此,利用索引会使数据库查询有惊人的性能提升。

为什么加索引后会使写入、修改、删除变慢?

然而, 事物都是有两面的, 索引能让数据库查询数据的速度上升, 而使写入数据的速度下降,原因很简单的,
因为平衡树这个结构必须一直维持在一个正确的状态, 增删改数据都会改变平衡树各节点中的索引数据内容,破坏树结构, 因此,在每次数据改变时,
DBMS必须去重新梳理树(索引)的结构以确保它的正确,这会带来不小的性能开销,也就是为什么索引会给查询以外的操作带来副作用的原因。

讲完聚集索引 , 接下来聊一下非聚集索引, 也就是我们平时经常提起和使用的常规索引。

非聚集索引和聚集索引一样, 同样是采用平衡树作为索引的数据结构。索引树结构中各节点的值来自于表中的索引字段。
假如给user表的name字段加上索引 , 那么索引就是由name字段中的值构成,在数据改变时, DBMS需要一直维护索引结构的正确性。如果给表中多个字段加上索引 , 那么就会出现多个独立的索引结构,每个索引(非聚集索引)互相之间不存在关联。
如下图

每次给字段建一个新索引, 字段中的数据就会被复制一份出来, 用于生成索引。 因此, 给表添加索引,会增加表的体积, 占用磁盘存储空间。

非聚集索引和聚集索引的区别在于, 通过聚集索引可以查到需要查找的数据, 而通过非聚集索引可以查到记录对应的主键值 ,
再使用主键的值通过聚集索引查找到需要的数据,如下图

不管以任何方式查询表, 最终都会利用主键通过聚集索引来定位到数据, 聚集索引(主键)是通往真实数据所在的唯一路径。

然而, 有一种例外可以不使用聚集索引就能查询出所需要的数据, 这种非主流的方法 称之为「覆盖索引」查询。
也就是平时所说的复合索引或者多字段索引查询。 文章上面的内容已经指出, 当为字段建立索引以后, 字段中的内容会被同步到索引之中。
如果为一个索引指定两个字段, 那么这个两个字段的内容都会被同步至索引之中。

先看下面这个SQL语句

//建立索引

create index index_birthday on user_info(birthday);

//查询生日在1991年11月1日出生用户的用户名

select user_name from user_info where birthday = ‘1991-11-1’

这句SQL语句的执行过程如下

首先,通过非聚集索引index_birthday查找birthday等于1991-11-1的所有记录的主键ID值

然后,通过得到的主键ID值执行聚集索引查找,找到主键ID值对就的真实数据(数据行)存储的位置

最后, 从得到的真实数据中取得user_name字段的值返回, 也就是取得最终的结果

什么情况下要同时在两个字段上建索引?

我们把birthday字段上的索引改成双字段的覆盖索引

create index index_birthday_and_user_name on user_info(birthday,
user_name);

这句SQL语句的执行过程就会变为

通过非聚集索引index_birthday_and_user_name查找birthday等于1991-11-1的叶节点的内容,然而,
叶节点中除了有user_name表主键ID的值以外, user_name字段的值也在里面, 因此不需要通过主键ID值的查找数据行的真实所在,
直接取得叶节点中user_name的值返回即可。 通过这种覆盖索引直接查找的方式, 可以省略不使用覆盖索引查找的后面两个步骤,
大大的提高了查询性能,如下图

数据库索引是什么?为什么要使用索引?相关推荐

  1. 合肥工业大学—SQL Server数据库实验五:创建和删除索引

    创建和删除索引 1. 用SQL语句建立索引 2. 用SQL语句删除索引Stuspno 1. 用SQL语句建立索引 (1)应用场景:在教务管理系统中,经常需要通过学生的姓名查询学生的基本信息,学生人数大 ...

  2. mysql慢时如何防止重复账户_如何进行mysql数据库的优化? --慢查询定位 --索引详解 -- 定时备份...

    mysql数据库优化的常见方法: 1.表的设计要合理(满足3NF) 3范式 2.创建适当索引[主键索引|唯一索引|普通索引|全文索引|空间索引] 3.对SQL语句优化---->定位慢查询(exp ...

  3. 数据库表设计索引外键设计_关于索引的设计决策 数据库管理系统

    数据库表设计索引外键设计 Introduction: 介绍: The attributes whose values are required inequality or range conditio ...

  4. Mysql数据库优化技术之配置篇、索引篇 ( 必看 必看 转)

    转自:Mysql数据库优化技术之配置篇.索引篇 ( 必看 必看 ) (一)减少数据库访问 对于可以静态化的页面,尽可能静态化 对一个动态页面中可以静态的局部,采用静态化 部分数据可以生成XML,或者文 ...

  5. 【数据库】第三章 事务、索引和SQL优化

    [数据库]第三章 事务.索引和SQL优化 文章目录 [数据库]第三章 事务.索引和SQL优化 一.事务 1.原子性 2.持久性 3.隔离性 4.一致性 二.索引 1.介绍 2.分类 3.底层实现 4. ...

  6. 数据库基础知识点汇总(事务,索引)

    目录 三大范式 索引 概念 使用场景 索引的类型有哪些,他们的区别是什么? 作用 正向 负面 为数据表建立索引的原则有哪些? 创建 查看 删除 注意事项 什么情况下不宜建立索引? 什么情况下索引不会触 ...

  7. Oracle数据库解决NULL值不走B树索引

    B树索引我们可以把它看成是书的目录,在这个目录中主要记录的是索引所对应的表列的值和这个值所对应的ROWID.在通常情况下,我们在表中增加索引的目的是增加表的查询性能,但是有几种情况,即使你在表中加入了 ...

  8. Mysql数据库(十一)unique index 唯一索引

    Mysql数据库(十一)unique index 唯一索引 唯一索引和普通索引: 1.都是能够加快搜索速度 2.唯一索引中的值不允许重复,普通索引的值允许重复 表contacts 建表语句如下,其中, ...

  9. mysql建立学号与课程编号的索引_数据库mysql 四约束 三范式 六索引

    mysql 四约束 三范式 六索引 1.MySQL 约束 1.约束的作用 分类 表列的primary key主键,unique唯一键,not null非空等修饰符常常被称作约束(constraint) ...

  10. 数据库知识梳理——Mysql建立、删除索引及使用

    一.索引的作用 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重. 在数据 ...

最新文章

  1. 面完字节跳动,才知道自己的数据结构与算法有多薄弱...
  2. 高级/专家工程师职位和面试题
  3. 云原生环境下对“多活”架构的思考
  4. 韩顺平 java笔记 第3讲 运算符 流程控制
  5. MySQL中leftjoin和rightjoin的区别
  6. ScreenCapture API – QTP截屏工具
  7. 华为2019年4月10日实习生笔试题
  8. html 设置整体字体,html font标签如何设置字体样式
  9. 十二烷基-β-D-麦芽糖苷/CAS号: 69227-93-6
  10. 足下校园C语言评估系统答案,江苏省江阴市南闸实验学校2020-2021学年八年级下学期第4周周练语文卷(word含答案))...
  11. python精通能赚钱吗_月入3千到月入10万,精通数据分析的人到底有多赚?
  12. bmp/gif/jpg图象最底层原理分析
  13. wifi android透传源代码,【终极版】ESP8266远程控制wifi透传模块带调试app
  14. 一摞python风格的纸牌(fluent python阅读)
  15. 高德地图API JS实现获取坐标和回显点标记
  16. 在线查字典/汉语字典大全/字典查询网站源码开发搭建
  17. 史上最详细店铺运营方案,新手必看!
  18. 麒麟KY-RTI分布仿真技术:前言
  19. dvi转vga没有合适的分辨率
  20. 天猫小黑盒再登场,这次是携手星巴克还带来“会说话”的星礼卡

热门文章

  1. MyEclipse破解 CI-2018.9.0版本
  2. 基于计算机视觉的裂纹检测方案
  3. SpringBoot项目中快速集成腾讯云短信服务SDK实现手机验证码功能
  4. 我的世界启动时要Java_我的世界启动时Java出现日志怎么办
  5. 已知文件url,批量下载文件
  6. SciPy库主要功能
  7. turn.js (翻页效果)总结
  8. rs485与modbus流程图_RS485通讯基础及通讯应用详解
  9. 十天学会单片机(2)点亮一个发光管
  10. SwitchResX for Mac(屏幕分辨率修改工具)