通过与 Jira 对比,让您更全面了解 PingCode

  • 首页
  • 需求与产品管理
  • 项目管理
  • 测试与缺陷管理
  • 知识管理
  • 效能度量
        • 更多产品

          客户为中心的产品管理工具

          专业的软件研发项目管理工具

          简单易用的团队知识库管理

          可量化的研发效能度量工具

          测试用例维护与计划执行

          以团队为中心的协作沟通

          研发工作流自动化工具

          账号认证与安全管理工具

          Why PingCode
          为什么选择 PingCode ?

          6000+企业信赖之选,为研发团队降本增效

        • 行业解决方案
          先进制造(即将上线)
        • 解决方案1
        • 解决方案2
  • Jira替代方案

25人以下免费

目录

mysql索引是怎么实现的

MySQL索引实现方式有:B+tree索引、Hash索引、Full-text索引。我们最常用的是B+tree索引,主键索引(也叫聚簇索引)本身就是一个B+tree索引树,非叶子节点存储主键id,叶子节点为一整行数据,叶子节点之间通过双向链表连接支持范围扫描。

一、mysql索引是怎么实现的

MySQL索引有哪些实现方式

MySQL索引实现方式有:B+tree索引、Hash索引、Full-text索引。

我们最常用的是B+tree索引,主键索引(也叫聚簇索引)本身就是一个B+tree索引树,非叶子节点存储主键id,叶子节点为一整行数据,叶子节点之间通过双向链表连接支持范围扫描,一般加的少数索引,普通索引都是B+tree索引。

Hash索引只能在memory存储引擎下使用,这里不过多描述,优点是查询快,hash取模O(1)检索,缺点不支持范围查询,出现hash冲突性能会降低。

Full-text索引主要对varchar,text加索引,使用倒排索引的方式,与搜索引擎实现方式相似。

为什么使用B+tree索引

先说结论,主要因为磁盘读写速度远远低于内存速度,传统的机械硬盘大概慢一万倍,固态硬盘慢100倍,故减少磁盘I/O次数是提升索引性能的重点。

根据局部性原理和磁盘预读,Linux操作系统进行磁盘I/O时,一般顺序读写4KB到内存的Page Cache中,之后再在内存中找到对应的数据返回回去,Mysql的B+tree每个节点为16KB,我们可以把16kb当作磁盘IO的最小单元。

局部性原理表现为:时间局部性和空间局部性。时间局部性是指如果程序中的某条指令一旦执行,则不久之后该指令可能再次被执行;如果某数据被访问,则不久之后该数据可能再次被访问。空间局部性是指一旦程序访问了某个存储单元,则不久之后,其附近的存储单元也将被访问。

那么为什么选择B+tree作为索引呢,B+tree降低了磁盘IO次数吗?为什么不用红黑树或者hash索引呢。

红黑树每个节点容纳1个key,树的高度为O(log➋ N),查询复杂度也是O(log➋ N),1000000条数据,树的高度为1000,最差需要扫描1000次才能查询到对应数据。

B+tree每个节点容纳M个key,树的高度为O(logm N),m越大,树高度越低,按照mysql一个page节点存储16kb来算,一个bigint主键是8个字节,一个节点可以容纳大概1000个主键(每个节点还存储了其他隐藏信息帮助节点内部检索),m就是1000,一千万条数据,树的高度大概是3层,只需要3次磁盘I/O加上几百次内存遍历查找,就可以快速定位到数据,这对查询性能的提升的巨大的,如果没有索引而进行全表扫描的话,大概需要上万次磁盘I/O。

故基于局部性原理和磁盘预读,B+tree适合在磁盘文件系统中做检索,红黑树更适合在内存中检索(比如java的hashmap,网络epoll的连接节点存储)。

为什么推荐使用自增ID作为主键呢,B+tree的构建过程是通过分裂和合并保持树的稳定的,如上图,若不是顺序插入的,树会进行频繁的分裂,导致额外的磁盘IO和CPU使用,可以使用此网站数据结构构建过程手动测试下。

另外mysql的除主键外的普通索引的叶子节点都是id,故id越小普通索引的占用磁盘空间越小,故推荐使用int或bigint来做主键(下文详细讲)。

延伸阅读:

二、索引分类

索引按照索引列是否是主键,分为主键索引和辅助索引(除主键列索引外,其他列的索引都是辅助索引)

辅助索引又可分为少数索引,普通索引,全文索引

主键索引:即主索引,根据主键建立索引,不允许重复,不允许空值;

少数索引:用来建立索引的列的值必须是少数的,允许空值;

普通索引:用表中的普通列构建的索引,没有任何限制;

全文索引:用大文本对象的列构建的索引,在MySQL5.6以下,只有MyISAM表支持全文检索。在MySQL5.6以上Innodb引擎表也提供支持全文检索。

相关文章