MySQL实现的一点总结(三)

下面看下前面提到的页类型:
表空间第一组第一区第一个页是FSR_HDR类型,包含:
File Header:上面展示过,用于标识、校验、形成页面双链等;
File Space Header:表空间整体属性,后详述;
XDES Entry[0~255]:表示本组的256个区;
Empty Space、File Trailer;
File Space Header:
Space ID:表空间ID;
Size:页面数;
Free limit:未初始化的最小页,后面的页尚未加入free链;
Frag n used:free_frag链已使用的页数;
List base node free、list base node free_frag、list node full_frag:free、free_frag和full_frag三个链表的基节点;
Next unused segment ID:新建段时用之前的最大ID自增,以保证段ID唯一;
List base node seg_INODES_FULL、list base node seg_INODES_FREE:上面说了INODE Entry表示段信息,所有的INODE Entry被集中放在页类型为INODE的页面中(即第一组第一区第三个页面),但段多了之后,一个页面可能放不下,所以做成俩INODE页面的链表,一个表示页面满了,另一个表示还有空间(同样是用了链表,不知啥情况),俩链表的基节点存在此处
由上可知,FSP_HDR页里面的file space header是关于表空间整体的,而XDES Entry数组是本组的区。其实除了第一组,之后的每一组第一页(XDES类型)的内容就是FSP_HDR去掉file space header,即就是存了本组256个区的信息
然后是IBUFF_BITMAP类型的页(每组第一个区的第二页),这个是每个组都有的,目的是为了减少二级索引更新时随机I/O对性能的影响,而开辟缓存change buffer,先在内存中修改二级索引(B+树),等空闲或相关页面被加载时再做真正修改
INODE类型页面:如前,存所有INODE Entry
File Header
List node for INODE page list:(如前,包括prev page&offset、next page&offset,形成双链)用于串成seg_INODES_FULL和seg_INODES_FREE,需要新页面时,从free_frag链中申请;
INODE Entry[0~84]
Empty space、file trailer
InnoDB默认为表建立以主键为索引的B+树(聚簇索引),用户添加某列为索引时,同样以此列值(默认联合主键以保证唯一性)建立一棵新的B+树。与主键索引不同的是,普通索引树的叶子节点不保存用户记录,而只存索引列值和主键,然后再用这个主键到主键索引的树中找完整的记录(回表)
重复一下:因为索引要求唯一性,so对于用户定义的非unique索引,建树时实际上以此列和主键作为联合索引(先比较列值,列值相同再比较主键——maybe列值相同时以主键排序有利于减少回表时的I/O?),同理,自定义的联合索引也不能保证唯一,so也会带着主键
因为查找这种普通索引需要回表,所以又叫二级索引
对于MyIsAm来说,记录不存在主键索引B+树的叶子上,而是单独存到一个文件中,树叶上只存记录的地址(二级索引),for定长记录,存行号,for变长记录,存偏移量,且插入记录时无需用主键排序,因为直接用地址找
B+树创建后根节点不再移动,B+树每层的页面形成双链,每页内的索引或记录形成单链,便于查找定位

引擎可根据扫描范围等来判断是否使用索引以及使用哪个索引,并非条件中有索引列就会使用它,应分析此索引能否缩小扫描范围并减少性能消耗,比如if用二级索引也是全表扫描的话还不如用主键全表扫描,还省了回表
联合索引中,只有在上一级相等的情况下,下一级才能缩小扫描范围(因为在树中上一级相等时按照下一级排序),ex:select * from xx where k_part1<=’b’ and k_part2 = ‘a’; 当扫描k_part1<b时,k_part2=a不能缩小扫描范围,只有在k_part1=b的记录中,可以在发现k_part2>a就停止扫描——不过可以扫描时可以提前过滤掉k_part2!=a的记录——称为索引条件下推
另外当结果需要order by且顺序符合索引时,可以直接出结果,而避免了文件排序,如order by k_part1,k_part2或order by k_part1 desc k_part2 desc(向左读),但desc、asc混用就不行了;另外联合索引还可用于group by
以上,可以总结一些原则:
只为用于搜索、排序或分组的列创建索引;
索引列值尽量不重复,类型尽量小(省空间和I/O);
字符串可以考虑只为前缀做索引(省空间,但是就不能order by了);
覆盖索引:只select索引中的列,则不需回表;
条件中的索引列单独出现,如where k2 * 2 < 4,此时无法使用k2索引;
新纪录插入使用主键自增,因为B+树是按主键排序的,新增记录主键如果无序则会造成页面频繁分裂;
避免冗余的索引

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值