首先说明一下:
MySQL并没有硬性规定只能支持到2000万左右的数据量。
其实,MySQL能够处理的数据量远远超过这个数字。无论是开源社区版还是商业版,
MySQL在适当的硬件和配置下,都能够支持非常大的数据集。
通常所说的“MySQL只能支持2000万左右的数据量”,是在谈论具体的一些使用场景时大概的估算值,
受到某些配置、硬件资源或设计上的限制。在这些情况下,MySQL的性能可能会遇到瓶颈。
这些瓶颈可能来自于硬件限制、表结构设计、配置不当、查询优化、并发处理等。
这里就不得提及数据库索引的构建,以及InnoDB存储引擎的结构和它是如何存储数据与索引的了。
索引是数据库中的一个数据结构,可以帮助快速定位到表中特定行的记录,就像书的目录能帮助你快速找到某个主题的章节一样。在MySQL的InnoDB存储引擎中,索引通常是使用B-Tree(具体来说是B+Tree)数据结构来构建的。
构建索引的过程如下:
InnoDB是MySQL的默认存储引擎,它支持事务、行级锁定和外键。它的主要结构包括:
在InnoDB中,表数据本身就是按照主键顺序存储的,这种结构被称为聚簇索引(Clustered Index)。每张表的聚簇索引是其主键索引,意味着表数据都存放在主键索引的B+Tree结构中的叶子节点上。如果表没有显式的主键,InnoDB会选择一个唯一索引代替;如果没有唯一索引,InnoDB会自动生成一个隐藏的row ID来作为主键。
对于非主键索引(也称为二级索引或辅助索引),叶子节点不直接存储行数据,而是存储相应行的主键值。当通过辅助索引查找数据时,会先在辅助索引的B+Tree中找到主键,然后再通过主键在聚簇索引中检索实际的行数据。
索引可以显著提高查询效率,尤其是在数据量大的表中。
但同时,索引也占用磁盘空间,并且在插入、更新和删除操作时需要额外的维护成本,因为不仅是数据本身,索引也需要相应地更新。
在数据库设计中,特别是当涉及到大量数据的时候,考虑B+树索引的层数是非常重要的。主键列被广泛使用bigint类型,这主要是因为bigint类型的整数范围很大(从-263到263-1),
能够支持极大量的数据行,这对于有大量数据的系统来说非常有用。
B+树索引的层数决定了查询需要多少次磁盘I/O操作才能找到指定的数据。
理论上,B+树的每增加一层,就能够索引更多的数据,但同时也意味着访问数据时需要更多的磁盘访问次数。
因此,数据库系统通常尽可能地减少这些层数。
假设我们使用的是InnoDB存储引擎,一个页(Page)默认是16KB大小,而一个bigint类型的索引大约需要8字节(实际上可能更多一点,因为还包括了页的指针,假设为14字节)。我们可以大概估算一下:
B+树的层数建议限制在3层以内,主要是基于性能的考虑。当B+树的层数增加时,每次查询数据所需的磁盘I/O次数也会增加,因为每一层都可能涉及到一次磁盘I/O(尽管数据库的缓存机制可以减少这种情况发生的频率)。磁盘I/O通常比CPU计算和内存访问要慢得多,因此,为了维持数据库查询的高性能,建议尽量减少层数。
现在我们来估算一下三层B+树能存放多少索引条目。以InnoDB存储引擎为例,它的默认页大小是16KB(16384字节)。
我们假设现在数据库中的每一条数据为1k,每个索引条目大小为14字节(如果包含事务ID和回滚指针的话),
那么每个数据页假设存储16条数据。
下面是计算过程:
这里是以bigint类型举例,当使用的类型不同时,存储的索引量不同,而且还与每行的数据大小有关。
因此“2000万的数据量是如何估算的”这个说法是错误的,我们要根据自己的业务场景,具体情况具体分析。
可以使用预估的方式,计算在B+树的层数为3时,最大的数据量,当数据量远大于这个数值时,可以通过增加内存的方式,或者分库分表解决查询慢的情况。
最后说一句(求关注,求赞,别白嫖我)
最近无意间获得一份阿里大佬写的刷题笔记和面经,一下子打通了我的任督二脉,进大厂原来没那么难。
这是大佬写的, 7701页的阿里大佬写的刷题笔记,让我offer拿到手软
求一键三连:点赞、分享、收藏
点赞对我真的非常重要!在线求赞,加个关注我会非常感激!@小郑说编程