mysql 存储引擎和索引

存储引擎

引擎 特性 文件
InnoDB 默认,支持事务,支持外键,支持行锁和表锁 .frm 文件存储表结构
.ibd 文件存储数据和索引
MyISAM 不支持事务,不支持外键,只支持表锁不支持行锁
专门维护了一个常量保存每个表的总记录数(count 很快)
MyISAM 强调的是性能,所以性能上优于InnoDB,但安全性和并发性较低
.frm 文件存储表结构
.MYD 文件存储数据
.MYI 文件存储索引
Memory 数据存在内存中,所以性能上来看是最好的,缺点也很明显,一旦宕机数据就没了 只有表结构文件(只有 frm 文件)

索引

索引是一种数据结构,目的是提高检索数据的效率,减少磁盘I/O,也是一个文件存放在磁盘中(Memery 这种引擎数据都在内存中,索引也不可能有实质的文件了)
有利有弊,索引也是需要维护的,所以索引越多维护的成本也增大
按照不同的规则可以划分出不同的类型,比如按照字段个数:单列索引,复合索引;是否主键:主键索引,非主键索引。按照索引的数据结构上又能分为:聚簇索引和非聚簇索引

索引类型 支持的存储引擎 数据结构 节点内容 特点
聚簇索引/主键索引 InnoDB b+tree 叶子节点存放整行数据
非叶子存放主键和数据页的关系
一半不超过3级,因为3级都差不多上亿的数据量了
主键如果没有顺序,插入效率会很低,因为索引是有序的,所以没有序的数据可能要修改整棵索引树
非聚簇索引/辅助索引/二级索引 InnoDB b+tree 和聚簇索引的区别是:叶子节点只存放主键 可能会回表(符合索引下推就不回表)
MyISAM 索引 MyISAM b+tree 和聚簇索引的区别是:数据对应在硬盘的地址 一定会回表,因为索引和数据文件都不是同一个
可以没有主键,因为不支持聚簇索引
Hash 索引 Memory hash 数据结构类似 java 的 HashMap,根据 key 算下标,然后取数据,大多数情况下时间复杂度是 O(1),查询效率相当高
  • b-tree 是一种数据结构,这种数据结构是叶子节点和非叶子节点都可能存放数据。但是数据库索引没有采用这种结构!
  • 为什么非聚簇索引叶子不也放整行数据,这样就能避免回表?数据冗余,比如10个非聚簇索引,就要放11份数据
  • InnoDB 能不能使用 Hash 索引?不能手动创建 Hash 的索引,但是如果是访问频繁的数据,内部会自动构建一个自适应哈希索引
  • 既然 Hash 索引查询效率高,为什么 InnoDB 不使用 Hash 要用 B+Tree?
    • 根据 key 得到下标然后得到数据的,如果是 like 或者范围查询就 gg 了,因为 key 都不是常量
    • 默认查询的结果集是没有顺序的,如果要 ORDER BY 内部会再次对结果集进行排序计算
    • 如果是联合索引,hash 值是多个列联合计算的,无法根据其中的一个列进行索引

InnoDB 聚簇索引数据结构

  • 索引的数据结构是 b+tree,每个数据页(目录页)是双向链表,数据页里面的数据是单向链表,为什么是 b+tree 后面会说到
  • 计算机与磁盘交互的基本单位是数据页(图中目录页也是数据页,为了区分 bTree 的叶子节点和非叶子节点的叫法而已),每个数据页大小16k
  • sql 不管走不走索引都要发生磁盘交互,因为索引也是文件。数据会放在多个数据页,索引的目的是提高检索效率减少磁盘IO次数
  • 比如要找 id=9 的数据,查询过程如下:
    • 先到根节点的目录页,里面是个单向循环链表,能确定在目录页19
    • 目录页19 里面的节点也是单向循环链表,能知道数据位于数据页21
    • 到数据页21 里面得到 id=7 的数据

b+tree 和 b-tree

B+Tree 只是叶子节点才存放数据,B-Tree 非叶子节点也可能存放数据,因为数据页的大小是固定的 16k,所以 B-Tree 更高瘦
B+Tree 查询更稳定,正因为有的数据放在目录页,而一个页的大小又是固定的,所以快的时候效率高有的时候就比较低

posted @ 2023-05-17 13:48  CyrusHuang  阅读(11)  评论(0编辑  收藏  举报