索引的底层

问题汇总

  1. 为什么mysql底层不用红黑树?

在数据量非常大的清空下,树的高度很高,查找效率下降。而B+树一个节点可以存储很多索引,每个节点中的索引按序排列,二分查找。所以树的高度可以大大降低

  1. h=3时,page_size=16KB,叶子节点每个索引+数据的大小为1KB,则整个B+树可以存放多少个数据
    1. 每个非叶子节点可存放索引16K/(8+6)=1170个索引
    2. 每个页可存放叶子节点 16K/1K=16
    3. 故总数据量 1170117016=2400w

image.png

  1. 索引的基本原理

索引用来快速寻找哪些具有特定值的记录,若无索引,则需要进行全表扫描
索引的原理就是:将无序的数据转变为有序的查询
一般来说,若不需进行范围查询,可使用hash来创建索引
否则一般通过B+树来创建索引结构

  1. mysql中索引类型对数据库性能的影响
    1. 普通索引:允许索引值重复
    2. 唯一索引:可以保证数据记录的唯一性
    3. 主键索引:特殊的唯一索引,一张表中仅能存在一个,主键用于唯一标识一条记录
    4. 联合索引:索引可以覆盖多个数据列,INDEX(columnA,columnB)
    5. 全文索引:通过建立倒排索引,可以极大提升检索效率,解决判断字段是否包含的问题。是目前搜索引擎使用的一种关键技术。ALTER TABLE tablename ADD FULLTEXT(column)

通过使用索引,在查询时会使用优化隐藏起,可大大提高查询效率,但在增删改时,对于主键索引和唯一索引来说,若其不在buffer pool中,需要从磁盘取出来判断唯一性,其余二级索引则可change buffer的merge技术,来实现提高增删改查的效率。

  • 索引需要占用物理空间存储
  • 若建立聚簇索引(叶子节点包含记录值),需要的空间会更大
  • 若非聚集索引(二级索引)很多,若聚集索引改变,非聚集索引也要进行变更
  1. mysql聚簇索引和非聚簇索引的区别

都是使用B+树的数据结构

  • 聚簇索引:索引和记录存放到一起,按一定顺序组织;找到了索引就找到了记录,数据的物理存放顺序和索引一致,相邻索引的数据也是相邻的
    • 优势:可以直接获取数据记录,不用再次间接访问;范围查询效率高,因为数据按索引从小到大排列。;适合于在排序的场合使用。
    • 劣势:
      • 维护索引昂贵:特别是在插入新行或主键被更新导致分页(page split)时。建议负载较低时,使用OPTIMIZE TABLE优化表,因为行数据移动时可能产生碎片
      • 若采用uuid作为主键,使数据存储稀疏(因为分表问题),就可能出现聚簇索引比全表扫描还慢的情况,建议使用int,auto_increment作为主键
      • 主键较大的情况下,会增加所有非聚集索引的大小;
  • 非聚簇索引:索引和记录分开存放(myisam),叶子节点存储的是索引和数据行地址;即根据索引先拿到行地址,然后再取磁盘查找数据。

Innodb选择主键的顺序:user-defined,unique,row_id;非聚簇索引均为辅助索引,叶子节点存储的是主键值
myisam使用的是非聚簇索引,非聚簇索引不同的树看起来没什么不同,索引树是独立的。

  1. 索引设计的原则

    查询更快,占用空间更小

      1. 适合索引的列出现在where子句中或连接子句中
      2. 短索引。若对长字符串列进行索引,应指定一个前缀长度,可大量节省存储空间
      3. 定义有外键列的数据一定要有索引【】
    • 不要
      1. 不要过度索引。索引需要额外磁盘空间,对索引的修改和插入都可能造成索引的重构,索引列越多,重构时间越长
      2. 更新频繁的字段不要创建索引
      3. 对于定义为text,image,bit的数据的列不要创建索引
      4. 基数较小的表不用索引
  2. 锁的类型有哪些?

基于锁的属性:共享锁,排他锁
基于锁的粒度:行锁,表锁,页锁,记录锁,间隙锁,临键锁
基于锁的状态(表级别):意向共享锁,意向排他锁

若事务A加锁成功后,就设置一个状态告诉后面的事务,当前表里已经加了一个排他锁,你们不能继续加锁了。后面的事务获取这个状态,就可以了解是否可以加锁,避免了对整个索引树的遍历去查找加锁状态,而这个状态就是意向锁

  • 意向共享锁:当一个事务需要对整个表加共享锁时,需要获得这个表的意向共享锁
  • 意向排他锁:当一个事务需要对整个表加排他锁时,需要获得这个表的意向排他锁
  • 共享锁:读共享;写互斥;支持并发读数据。读时不可修改数据,避免出现重复读
  • 排他锁:读写均互斥。避免出现脏读,幻读,不可重复读
  • 行锁:锁住表的某一行或多行数据;粒度小,加锁简单,冲突小;会造成死锁【比如说两个事务分别持有某个表两个行的锁,然后又互相请求修改对方的行,即造成死锁】
  • 记录锁:行锁的一种,锁住表的某一行记录;精确条件命中,命中的条件字段时唯一索引。
  • 表锁:锁住整个表;粒度大,加锁麻烦,冲突大;
  • 页锁:介于行锁和表锁之间的一种锁;一次锁定相邻的一组记录;开销介于行锁和表锁之间;会出现死锁;
  • 间隙锁:行锁的一种,锁住表记录里某个区间,当相邻表id之间出现空隙则会形成一个区间【左开右闭】
  • 临建锁:行锁的一种,时记录锁和间隙锁的组合;临建锁会把查询出来的记录锁住,同时将改范围查询内的所有间隙锁住,再把下一个区间锁住
    • 触发条件:范围查询并命中,查询命中了索引
  1. mysql执行计划怎么看?(type)
  2. 事务的基本特性(ACID)和隔离级别

    事务的最终目的是一致性,故事务通过原子性、隔离性和持久性来达成这个目的 一致性简单的来说:比如说对于唯一id的操作,事务处理前是唯一的,事务提交后也是唯一的,这就是一致性

原子性:事务操作要么全部成功要么全部失败
一致性:数据库总是从一个一致性状态转变为另一个一致性状态。比如A转账给B100块,但A只有90块,支付之前数据库里的数据都是符合约束的,但如果事务执行成功了,当前数据库便破坏了约束,因此事务不能成功。这里即事务提供了一致性保证
隔离性:一个事务的修改再最终提交前,其余事务不可见
持久性:事务提交后,所作的修改会永久保存到数据库中。

  1. 主从同步原理?

image.png
image.png
全同步复制:需要等待10个从节点全部备份完成
半同步复制:假设10个从节点,只要有一个从节点返回ACK,就认为从库备份完成

  1. 简述Myisam和innodb区别

image.pngimage.png

联合索引的底层结构如何

image.png
image.png
最左前缀法则,只有红框会使用联合索引