3分钟读了解InnoDB索引

什么是索引

索引是一种为表提供快速查找能力的数据结构,通常用树型结构表示。

为什么使用树形结构?
为了加速查找速度,常见有两类:

  1. 哈希
    例如HashMap,插入/删除/修改/查询的时间复杂度都是O(1)

  2. 例如平衡二叉树,插入/删除/修改/查询的时间复杂度都是O(lg(n))
    不管是读请求还是写请求,哈希类型的索引都要快一些,那为什么要设计成树形呢?
    这与SQL的需求有关(任何设计都来源于需求):
    对于一个精确查询的SQL,例如:select id from t where name = 'dingxiaoyuan';确实是哈希更快
    但是对于范围查询(>、<等),哈希的时间复杂度会退化成O(n),平衡二叉树自身就是有序的,所以能够保持O(lg(n))

InnoDB的自适应哈希就是哈希索引,是对查询的一种优化,所以说并不是不用。

为什么使用B+树?
下面我们逐一分析原因:
1. 为什么不使用二叉搜索树?

  • 数据量大时,树的高度比较高,查询效率比较低
  • 每个节点只有一条记录,发生多次磁盘I/O

2. 为什么不使用传统的B树?

B树适用于索引的原因:

  • B树是一颗m叉树,可以有多个子节点,可以减低数据的高度
  • 每个节点可以有多个记录,可以充分利用预读机制,减少磁盘I/O
    对于B树而言,每个节点的数据存储在连续区域内,如果节点大小与操作系统页大小相等,可以充分利用与独特性

    磁盘预读:磁盘不是按需读写,每次都会读取一页数据
    局部性原理:一个数据被用到时,其附近的数据大概率会被用到

但是,对于范围查询存在两个特殊的情况:

  • 情况一:符合条件的数据在父节点甚至根节点
  • 情况二:符合条件的数据在兄弟节点

对于这两种情况,可以使用下面的优化方案:

  • 对于情况一
    中间节点不再保存数据,而是全部放入叶子节点
  • 对于情况二
    不再通过遍历树寻找叶子节点,而是直接建立叶子节点之间的链接关系

这就是B+树,如图:

最后,量化一下B+树如何降低树的高度
假设每个节点大小是4KB,一个索引Key8字节,高度为3

  1. 每个节点可以存储4KB/8B=500个Key
  2. B树的特性。m叉树满足公式,m/2<= 每个节点Key数量(500) <=m,因此最多有1000个分叉
  3. 那么
Key数量 占用空间
层级1 500 4K
层级2 500 * 1000 = 50W 4M
层级3 500 * 1000 * 1000 = 5亿 4G

对于二叉树存储相同数量的索引,需要的高度约为lg(2.5亿)

索引分类

在InnoDB中,索引可以分为两大类

  1. 聚集索引
    聚集索引一个特殊的索引,表数据和索引在一起存储。通常指的就是主键索引
    因为这个特性,InnoDB表必须有聚集索引:

    • 如果定义了PK,那么PK就是主键索引
    • 如果没有定义PK,那么第一个非空唯一索引就是聚集索引
    • 如果没有PK和合适的唯一索引,那么InnoDB生成一个包含row-id的合成列作为聚集索引
      row-id是一个6字节的属性,插入行时单调递增
  2. 辅助索引
    与聚集索引不同,辅助索引可以有多个,并且只存储定义为索引的列和主键

因此:

  • 对于主键查询,只需要遍历一次聚集索引树
  • 对于其他索引列查询,需要遍历一次辅助索引树找到主键,再遍历一次聚集索引树
    例如:

table t ( id pk ,name key ,sex )

对于 select * from t where name = 'a' 的情况,会先通过辅助索引定位检索到叶子,得到id=5,再通过聚集索引定位行记录

索引的优化

自适应哈希

为什么要有自适应哈希?
对于select * from t where name = 'm';
每次执行都需要遍历两次索引树,与哈希结构相比效率非常低。因此,InnoDB为频繁访问的数据建立哈希索引。

自适应哈希由InnoDB自动构建,以索引树为基础,选择任意长度的Key。当有访问时,由哈希直接得到数据

索引条件下推

ICP是索引作为筛选条件时的一种优化。筛选条件下推到存储引擎,只返回符合条件的数据,而不是所有数据。
例如:(zipcode、lastname、firstname)是联合索引

select * from user
    where zipcode = 9527
    and lastname like '%ing%'
    and address like '%ian%'
  • 不使用ICP
    返回zipcode=9527的所有记录,然后再做其他条件的筛选
  • 使用ICP
    返回zipcode=9527的记录前,会检查是否满足lastname的条件,然后返回符合索引条件的数据

结论:不开启ICP会比开启ICP的情况,多返回不满足lastname条件的数据

覆盖索引

如果查询需要返回的列是定义的索引,那么可以通过索引直接返回数据,而不需要在从聚集索引中检索主键

索引的构建过程

排序索引构建是一种自底向上的算法,采用批量加载的方式代替传统的逐条插入方式。
索引的创建过程概括为三个阶段:

  1. 扫描聚集索引,生成索引条目并添加到排序缓冲区。当缓冲区已满时,排序索引并写入临时文件中。
  2. 对所有文件中的索引合并排序
  3. 将排序后的索引写到B-tree

B+树的构建过程

  1. 初始化阶段,树的每一层都有一个最右节点,作为下一个插入的节点
  2. 按顺序插入索引
  3. 插入时发现空间不足,那么在右侧创建新节点作为最有节点,插入的同时向父节点赋值

注意:索引构建会禁用重放日志,通过检查点机制强制脏页写磁盘

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容

  • InnoDB体系架构 上图简单显示了InnoDB存储引擎的体系架构图中可见,InnoDB存储引擎有多个内存块,可以...
    Rick617阅读 4,027评论 0 6
  • 索引 数据库中的查询操作非常普遍,索引就是提升查找速度的一种手段 索引的类型 从数据结构角度分 1.B+索引:传统...
    一凡呀阅读 2,910评论 0 8
  • lnnoDB是事务安全的MySQL存储引擎, 设计上采用了类似于Oracle数据库的架构。 通常来说,InnoD...
    好好学习Sun阅读 1,488评论 0 5
  • 聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。比如,InnoDB的聚簇索引使用B+Tree的数据结构存储...
    sherlock_6981阅读 1,861评论 0 2
  • 表层习惯:午睡 训练结果;差,没有按照规定的时间睡觉,没有按照睡到规定的时长 原因分析;上午的事情一直忙到1点多,...
    傲娇的岛阳君阅读 154评论 0 0