在innoDB中,聚集索引B+树将数据存储在叶子节点中。我相信它存储实际的数据记录,而不是指向数据的指针。这与 postgres 不同,其中索引叶节点存储指向堆文件的指针。
这会产生一些严重的影响。
这些是真的吗?
来自postgres,由于索引文件不存储数据,索引大小应该小得多,因此更有可能适合内存。但在 innoDB 中,聚集索引很可能无法容纳在内存中,因为索引本质上就是表。
一些来源 来自link,在MySQL的InnoDB下,表数据和主键索引存储在同一个数据结构中。
这些都是真的。
B+Tree包含了所有数据;即所有列,包括
PRIMARY KEY
列。按PK排序;每个块为 16KB。因此,通常每个块并不完全满。
而且,由于存在大量“开销”,因此数据所需字节的估计值应乘以 2 到 3,以获得所有块所需的磁盘空间。
PK 的“点查询”是一个简单的 BTree 查找,而且速度非常快。十亿行可能有大约 5 层 BTree。
数据块、二级索引和其他杂项都缓存在RAM中的“缓冲池”中,其大小由
innodb_buffer_pool_size
配置。对于 8GB RAM,我建议不要超过 6G。
将 PK 嵌入数据的开销约为 1%。 (因此,我对你的“大于实际数据大小”表示怀疑。)这 1% 是对除了当然必须存在的数据块之外所需的额外“索引”块的粗略估计。
作为缓存,块根据需要来来去去。因此,即使只有 5GB 缓存,您的 100GB 数据也能正常工作。缺点是需要额外的 I/O。根据访问模式,可能不会有太大的缺点。
MySQL 不会尝试“将索引保留在 RAM 中”(或类似的东西)。它仅以最近最少使用的模式对块输入/输出进行洗牌。如果您的访问模式不涉及表扫描或索引扫描,我建议“索引无法放入内存”不是一个大问题。