我们正在从 MySQL 迁移到 PGSQL,我们有一个 1 亿行的表。
当我试图确定两个系统使用了多少空间时,我发现表的差异要小得多,但发现索引的差异很大。
MySQL 索引占用的大小比表数据本身大,而 postgres 使用的大小要小得多。
在挖掘原因时,我发现 MySQL 使用 B+ 树来存储索引,而 postgres使用B-tree。
MySQL 对索引的使用有点不同,它将数据与索引一起存储(由于增加了大小),但 postgres 没有。
现在的问题:
比较数据库中的 B-tree 和 B+ 树,最好使用 B+tree,因为它们更适合范围查询 O(m) + O(logN) - 其中范围和查找中的 m 在 B+tree 中是对数的?
现在在 B 树中,对于范围查询,查找是对数的,因为它没有数据节点的链表底层结构,所以它会上升到 O(N)。话虽如此,为什么 postgres 使用 B-trees?它对范围查询是否表现良好(确实如此,但它如何在内部处理 B 树)?
上面的问题是从postgres的角度来看的,但是从MySQL的角度来看,为什么它比postgres使用更多的存储空间,在现实中使用B+trees有什么性能优势呢?
我可能错过/误解了很多事情,所以请随时在这里纠正我的理解。
编辑以回答 Rick James 的问题
- 我正在为 MySQL 使用 InnoDB 引擎
- 我在填充数据后建立了索引 - 与我在 postgres 中所做的相同
- 索引不是唯一索引,只是普通索引
- 没有随机插入,我在 postgres 和 MySQL 中都使用了 csv 加载,然后才创建索引。
- 索引和数据的 Postgres 块大小都是 8KB,我不确定 MySQL,但我没有更改它,所以它必须是默认值。
- 我不会称这些行很大,它们有大约 4 个文本字段,长度为 200 个字符,4 个十进制字段和 2 个 bigint 字段 - 19 个数字长。
- PK 是一个 bigint 列,有 19 个数字,不知道这算不算笨重?应该在什么规模上区分笨重与非笨重?
- MySQL 表大小为 600 MB,Postgres 大约 310 MB,包括索引 - 如果我的数学是正确的,这相当于大 48%。但是有没有一种方法可以单独测量 MySQL 中的索引大小,不包括表大小?我猜这可以带来更好的数字。
- 机器信息:我有足够的 RAM - 256GB 来将所有表和索引放在一起,但我认为我们根本不需要遍历这条路线,我没有看到它们之间有任何明显的性能差异。
附加问题
- 当我们说碎片发生时?有没有办法进行碎片整理,以便我们可以说除此之外,没有什么可做的。顺便说一下,我正在使用 Cent OS。
- 有没有办法在 MySQL 中测量索引大小,忽略主键,因为它是聚集的,这样我们就可以实际看到什么类型占用了更多的大小(如果有的话)。