高并发之存储篇:关注下索引原理和优化吧!躲得过实践,躲不过面试官!


不管是啥业务 , 最终数据都要落地 , 数据库这一环是肯定少不了的 。 随着业务发展 , 并发越来越高 , 数据库很容易成为整个链路的短板 。 这也是大厂面试中比较常被问到的 。 而调优的第一步 , 都是从sql语句、索引入手 。 先得保证单个数据库执行没问题 , 才会有更高层次的分库分表、弹性、容灾等等 。
Part1为什么Kafka不需要我们关心索引 , 而Mysql却需要?
Kafka 和 MySQL 虽然最终数据都是落磁盘 , 但是两者在用途和数据查询方式上有着很大的差异 , 所以决定了数据的存储结构不同 , 进而决定了索引的复杂程度 。
我们先看下kafka的存储结构:
高并发之存储篇:关注下索引原理和优化吧!躲得过实践,躲不过面试官!
本文插图
由于 kafka 的定位是进行稳定的高性能数据读写 。 所以对磁盘来说 , 是采用顺序读写的方式 , 落在了一些 .log 文件中 , 并以基准偏移量补0命名 。
为了实现高速查找 kafka 创建了稀疏索引文件( 隔一段数据创建一条 , 而非全量) , 即index文件 。 其中维护消息的 offset 和 .log文件的物理位置 。 通过二分查找快速定位log文件并顺序扫描找到目标 。
所以 , kafka的索引组织方式是相对简单、方案相对固定 , 但MySQL却不行 。 Mysql是关系型数据库 , 是为了支持复杂的业务数据查询而创建的 ,查询方式、数据获取需求多种多样 , 要求MySQL具备更加复杂的索引机制来加速复杂业务查询场景。
Part2MySQL数据怎么被组织 [1] [2]
以InnoDB存储引擎来看mysql数据存储:
高并发之存储篇:关注下索引原理和优化吧!躲得过实践,躲不过面试官!
本文插图
参考了三本资料 , 基本把最重要的部分都概括了
数据被分了多个逻辑层:行->页->区块->段->表空间 。
我们知道 , InnoDB存储引擎表是Index organized的( 数据即索引 , 索引即数据) , 他们都维护在一个B+树上 , 数据段就是叶子节点 , 索引段就是非叶子节点;
而我们划分的段、区块 其实都是为了利用操作系统的资源( 比如每次从磁盘加载到内存的数据大小按区块来约定等等`)来达到更高效读写的目的 , 逻辑划分的 。
其中页是MySQL和磁盘交互的最小单位 , 怎么从页找到行 , 怎么聚合到块、到段再到空间呢 。
1数据记录最小单位-- 行
【高并发之存储篇:关注下索引原理和优化吧!躲得过实践,躲不过面试官!】从上面总图中摘出一条记录的结构如下图:
高并发之存储篇:关注下索引原理和优化吧!躲得过实践,躲不过面试官!
本文插图
我们可以看到 , 记录头中除了行号 , 还有下一条记录的标识 next_record, 所以 , 我们可以通过 next_record 将记录连接起来 , 以 单向链表 的形式 , 所以这就决定了 , 当我们在记录链中寻找某记录时 , 只能顺序遍历 , 这也决定了一条数据链不会太长 。