Mysql索引问题

Mysql索引问题

1.页分裂问题,数据不连续导致也分裂有什么弊端?怎么避免或者有什么机制维护这个连续?

首先要明白页跟数据行的关系。 InnoDB在叶子上存储数据。一个节点就是一页。
一个页可以存储多行数据,按照主键的顺序存储。当数据是顺序插入的时候,一页写满了,就申请一个新的页。
如果是随机插入,在指定位置的页已经写满了(或者到达了分裂阈值)的时候,就会发生页结构的调整(即B+Tree的节点的分裂)。

2.索引用到文件排序 Using filesort,该怎么优化?

Using filresort代表:不能使用索引来排序,用到了额外的排序。 例如:查询用到了a字段上的idx_a,但是后面有order by
b。 一些优化方式:

  1. 建立联合索引idx(a,b)
  2. 不使用MySQL的排序,改成在代码中排序

3.一个3层的树,为什么要做三次io?为什么一次不能查出所有数据的节点以及相对应数据

页(Page)是 Innodb 存储引擎用于管理数据的最小磁盘单位,也就是InnoDB一次I/O(读写磁盘)的逻辑单位大小是16K(默认)。
InnoDB把B+Tree的节点设置为一个Page,所以,读取一个节点,就会发生一次I/O。

3-1.为什么要固定Page大小,而不是需要多少数据,读取多少数据(按需读取)?

设置页的大小与磁盘的预读取特性有关系。局部性原理认为:当一个数据被用到时,其附近的数据也通常会马上被使用。所以顺序读取附近的数据,可以提升I/O效率。每次都至少读取一页

3-2.为什么不把Page设置得更大?这样一次读取到的数据不就更多了吗?

官网有解释,默认的16KB大小,在涉及表扫描和批量更新的业务场景中更实用,效率已经很高了。

4.如果一条数据1k,一个页可以放16条数据,如果删除其中两条,这两条硬盘空间会不会被回收?如果回收,会造成页移动(或者merge?),如果不回收,又会造成读取的页存在空洞。怎么解决?

删除页中的行数据时,不会物理删除,而是先标记为删除,这时空间可以被其他记录实用。
当页中删除的记录达到MERGE_THRESHOLD(默认页体积的50%),InnoDB会开始寻找最靠近的页(前或后)看看是否可以将两个页合并以优化空间使用。

5.表没主键,但有非null的列,此列有重复的值,这样也是聚集索引吗?

  1. 如果我们定义了主键(PRIMARY KEY),那么 InnoDB 会选择主键作为聚集索引。
  2. 如果没有显式定义主键,则 InnoDB 会选择第一个不包含有 NULL 值的唯一索引作为主键索引。
  3. 如果也没有这样的唯一索引,则 InnoDB 会选择内置 6 字节长的 ROWID 作为隐 藏的聚集索引,它会随着行记录的写入而主键递增。

所以答案:no

6.辅助索引什么情况下查询需要回表,什么情况下不需要回表?

select 的列,包含在了使用的索引中。
就像我们要查看第12章的标题,这个标题已经在目录中了,就不用翻到具体页码查看了。
例如索引是index(a,b,c),select 索引里面的列(包括select a,select b,select c,select a,b select a,c select b,c,select a,b,c),都不需要到主键索引的叶子节点获取完整数据,此时不需要回表。

7.如果b+树中出现大量的删除和新增操作的时候,mysql是怎么优化避免这种问题的?

  1. 减少对主键索引的修改
  2. 建议在顺序递增的字段上创建主键索引

8.联合主键也是聚集索引吗?如果是的,排序如何处理呢?

在InnoDB中,主键就是聚集索引。所以不管是单列还是多列,都是聚集索引。
联合索引是一个复合结构,按照第一个字段排序。
聚集索引
主键索引

9.千万级的表用了索引,IO是在什么时候产生的?第一次查询的时候还是提前把数据读到内存?建了索引的表是不是数据都会放在内存中?

并不是所有的数据都放到buffer pool中,它的大小是有限的,默认128M,所以只能存储最常用的,最热的数据(通过LRU淘汰)。
读取一个页,就是一次IO。

10.辅助索引在调用主键索引的时候,会经历多次I/O吗?辅助索引中回表是回到主键索引吗?

加载B+Tree的一个节点就是一次I/O。回表是从辅助索引到主键索引。

11.在使用"%zi"的时候,索引下推了,还会使用到索引吗?

加索引从Server下推到存储引擎,会利用下推的条件,对索引进行过滤。

12.mysql存储中文 使用的编码是Unicode吗?

Unicode是字符集。UTF-8是编码规则。保存中文可以用utf8mb4。
U need this

13.辅助索引那个 为什么不直接存数据的地址 ,还要回表 多麻烦 ,主键索引中存放的应该是数据在磁盘上的地址信息么?

因为页分裂会导致数据的地址发生变动。
主键索引的叶子节点,直接存放完整的数据。

14.Redo.log 和db文件都是在磁盘上的,为什么写redo.log 是顺序io 写db文件就是随机IO呢?为什么先写入日志文件可以提高效率?

当buffer pool中有很多数据等待刷脏的时候,写入redo log是顺序追加写入的。
而这些数据在磁盘中的位置不一定是连续的(比如操作id=1 id=9,插入 name =‘a’ name = ‘s’),每次都要重新寻址,所以是随机I/O。
数据写入到redo log里面就有了保障,刷盘就不需要那么频繁了,提升了系统的吞吐量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值