mysql 索引的初步认识

在数据库中,索引是一种排好序,高效获取数据的数据结构。贴上一个学习数据结构的网站:www.cs.usfca.edu/~galles/vis...

一. 为什么数据库要通过索引来查询数据,一条条数据比对不就好了.

在实际查询过程中,比如select * from table where name='张三'。这条语句在没有索引的情况下,他会逐行比对,每次从磁盘获取一条数据比对一次,直到找到张三这条数据。从磁盘读取数据时比较慢,毕竟一次磁盘IO是低效的,这个时候索引就诞生了。

二. 为什么Mysql偏偏选择B+树作为索引数据结构,而不是二叉树,红黑树,B树。

  1. 如果是二叉树,是什么样子。比如主键就是一种索引,在自增的情况下,从1开始自增将会呈现下图所示,仅仅只有7个数据,二叉树的高度就有7层。如果是几百几千万条记录,树的高度也会是几百几千万。这样显然是不合适,如Sql语句 select * from table where id='7',这样得查找7次才能找到所需要的值。
  1. 如果是红黑树,同样以主键自增为例,7个数据的树的高度是3层,比二叉树好一些,节点的数据过多时,它会发生一次自平衡,所以他也叫做平衡二叉树,在面对几百万几千万数据时,树的高度也会达到几十或者几百万。同样不能作为索引的数据结构
  1. B树行不行呢,由于B+树和B树有些像,所以放在一起比较,我们来看看。上面的是B树,下面的是B+树,注意mysql的B+树经过改良后的,他的数据结构不是呈现下面的这个样子
  1. mysql的B+树,它是B树的一个变种,上图是B+树,下图是B树。这俩者有什么区别,

    B+树非叶子节点是没有数据的,他是为了存储更多索引的才这么设计,叶子节点包含了所有索引字段,叶子节点之间用指针链接,并且从左到右依次递增,这也是为什么他可以支持范围查询。以主键索引为例也叫聚集索引,叶子节点的上包含了这一条记录的所有数据。

    B树从左到右依次递增,但是叶子节点之间是没有指针的,所有的索引元素是不重复的这是它的一个特点

    这就回到了B树能不能作为索引的数据结构的问题上来,反过来先看B+树的表现如何,B+树的一个节点相当于一个一页,大概有16K,用 show GLOBAL STATUS LIKE 'Innodb_page_size' 这条Sql语句可以看到16384.不推荐改这个值,这个是mysql经过很多次优化得出的结果。假设一个字段字段8个字节,6个字节的指针地址(指向下一个节点),16K除以14个字节。那么一页可以存放1170个元素,下一个节点也是1170个元素,假设有三层,叶子节点1一个元素1KB,则有16个元素,则1170乘以1170乘以16等于俩千多万条数据,这样看来俩千多万条数据三层树的结构,加上B+树的特性刚好合适作为索引的数据结构。

    至于B树合适吗,叶子节点和非叶子节点都包含数据,那么在一页当中,存放的索引肯定就比B+树要少很多,树的高度就不止三层这么少了,仅仅这一条就作为索引的数据结构就不太合适。

三. 什么是回表查询

数据库innodb存储引擎,除了主键索引之外,还的索引,非主键索引,也就是二级索引,比如联合索引,当然联合索引也选择了B+树作为索引结构,它的叶子节点存储的是主键,当select语句没有覆盖联合索引的字段时,数据库会获取到叶子节点中的主键数据,再通过主键去主键的B+树上去查询,这种操作叫做回表,主键索引也叫做聚集索引。至于为什么二级索引叶子节点不像主键索引那样,存放所有数据,那得多放三四份甚至更多,这会浪费更多磁盘空间,同时插入一条数据的时候,为了一致性,主键索引和二级索引全部插完成,才能讲它插入完成,否则可能会出问题。

四. 为什么推荐innodb必须建主键,并且是整型的自增主键

当不建主键会发生什么,mysql当中,它会在所有列当中,选一列都不相等的一列来组织那棵B+树,如果没有一列是被选中,会自己建一列隐藏列来维护唯一ID,将其来组织B+树,数据库的资源是很宝贵的,这样的事情让mysql来做是不合适,增加mysql的工作。

主键最好是整型的是因为在插入数据的时候它会比大小,如果非整型它会一个个的字符比大小,这样肯定是整型比非整型的要快得多。如果插入的是整型数据不是自增的,mysql的B+树是一个排好序的数据结构,为了维持排好序,它会发生一次或者多次自平衡,比大小,努力使新加入的数据放到一个合适的位置,直到按照一定的顺序排列。

相关推荐
科技小花4 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸4 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain4 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希5 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神5 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员5 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java5 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿6 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴6 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存
YOU OU6 小时前
三大范式和E-R图
数据库