4、索引问题

245 阅读2分钟

问题:mysql聚簇索引,覆盖索引,底层结构,主键索引,没有主键怎么办,会自己生成主键为什么还要自定义主键,自动生成的主键有什么问题

Q1:mysql聚簇索引,覆盖索引,底层结构

聚簇索引(主键索引):索引下对应整行的值

clipboard.png

非主键索引:索引下对应主键的值

查询过程:非主键索引查询时找到对应的主键后,再带着主键去主键索引查找对应的行数据,这一过程也称为回表

避免回表(覆盖索引):即非主键索引查询到的值就是需要的返回值,则不需要再回表,这就是所谓的覆盖索引

  • 前提知识:当一张表将某个列设为主键的时候,则该列就是主键索引

Q2:主键索引,没有主键怎么办,会自己生成主键为什么还要自定义主键?

1、如果定义了主键,定义的主键会作为主键索引

2、如果没有定义主键,会使用第一排非空的唯一索引作为主键索引

3、如果以上两点均不满足:那么InnoDB会自动生成一个不可见的名为row_id的列名为GEN_CLUST_INDEX的聚簇索引,该列是一个6字节的自增数值,随着插入而自增--补充:该全局row_id在代码实现上使用的是bigint unsigned类型,但实际上只给row_id留了6字节。

这种设计就会存在一个问题:如果全局row_id一直涨,一直涨,直到2的48幂次-1时,这个时候再+1,row_id的低48位都为0,结果在插入新一行数据时,拿到的row_id就为0,存在主键冲突的可能性。

Q3:自动生成的主键有什么问题?

  • 使用不了主键索引,查询会进行全表扫描
  • 影响数据插入性能,插入数据需要生成ROW_ID,而生成的ROW_ID是全局共享的(InnoDB 维护了一个全局的 dictsys.row_id,所有未定义主键的表都共享该row_id),并发会导致锁竞争,影响性能