Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgres使用btree索引与MySQL B+;树_Mysql_Performance_Postgresql_B Tree_B Tree Index - Fatal编程技术网

Postgres使用btree索引与MySQL B+;树

Postgres使用btree索引与MySQL B+;树,mysql,performance,postgresql,b-tree,b-tree-index,Mysql,Performance,Postgresql,B Tree,B Tree Index,我们正在从MySQL迁移到PGSQL,我们有一个1亿行的表 当我试图确定两个系统都使用了多少空间时,我发现表的差异要小得多,但索引的差异却很大 MySQL索引占用的空间比表数据本身大,postgres使用的空间小得多 当深入研究原因时,我发现MySQL使用B+树来存储索引和postgres B-树 MySQL对索引的使用略有不同,它将数据与索引一起存储(由于索引的大小增加),但postgres没有 现在问题是: 比较数据库上的B-树和B+树,最好使用B+树,因为它们更适合范围查询O(m

我们正在从MySQL迁移到PGSQL,我们有一个1亿行的表

当我试图确定两个系统都使用了多少空间时,我发现表的差异要小得多,但索引的差异却很大

MySQL索引占用的空间比表数据本身大,postgres使用的空间小得多

  • 当深入研究原因时,我发现MySQL使用B+树来存储索引和postgres B-树

  • MySQL对索引的使用略有不同,它将数据与索引一起存储(由于索引的大小增加),但postgres没有

现在问题是:

  • 比较数据库上的B-树和B+树,最好使用B+树,因为它们更适合范围查询O(m)+O(logN)-其中范围中的m和查找在B+树中是对数的

    现在,在B-树中,范围查询的查找是对数的,因为它没有数据节点的链表底层结构,所以它最多可以达到O(N)。既然如此,为什么postgres会使用B树呢?它在范围查询中是否表现良好(确实如此,但它如何在内部处理B树)

  • 上面的问题是从postgres的角度来看的,但是从MySQL的角度来看,为什么它比postgres使用更多的存储空间,实际上使用B+树的性能优势是什么

我可能错过了/误解了很多东西,所以请随时纠正我的理解

编辑以回答里克·詹姆斯的问题

  • 我正在使用InnoDB engine for MySQL
  • 我在填充数据后建立了索引——和我在postgres中做的一样
  • 索引不是唯一的索引,只是普通索引
  • 没有随机插入,我在postgres和MySQL中都使用了csv加载,只有在这之后我才创建了索引
  • 索引和数据的Postgres块大小都是8KB,我不确定MySQL是否为8KB,但我没有更改它,所以它必须是默认值
  • 我不会称这些行为大行,它们有大约4个200个字符长的文本字段,4个十进制字段和2个bigint字段-19个数字长
  • P.K是一个有19个数字的bigint列,我不确定这是否庞大?在什么尺度上应该区分大型和非大型
  • MySQL表的大小是600 MB,Postgres大约是310 MB,包括索引——如果我的计算正确的话,这相当于大了48%。但是有没有一种方法可以在MySQL中单独测量索引大小(不包括表大小)?我想这会带来更好的数字
  • 机器信息:我有足够的RAM-256GB将所有的表和索引放在一起,但我认为我们根本不需要遍历这条路径,我没有看到它们之间有任何明显的性能差异
其他问题

  • 当我们说分裂发生时?有没有一种方法可以去碎片化,这样我们就可以说,除此之外,没有什么可以做的。顺便说一下,我正在使用Cent OS
  • 有没有一种方法可以测量MySQL中的索引大小,在主键聚集时忽略它,这样我们就可以真正看到什么类型占用了更多的大小(如果有的话)

在数据库中,您经常会询问谁提供了一些数据范围,如id从100到200。
在这种情况下

  • 对于每个条目,B-Tree都需要遵循从根到叶的路径来获取数据指针
  • B+-树木可以“行走”穿过树叶,并且只能第一次沿着路径到达树叶(即对于id 100)
这是因为B+-Trees只在leaf中存储数据(或数据指针),并且这些leaf是链接的,因此可以执行快速顺序遍历

B+树

另一点是:
在B+树中,内部节点只存储指向其他节点的指针,而不存储任何数据指针,因此指针的空间更大,所需IO操作更少,并且可以在内存页中存储更多节点指针


因此,对于范围查询,B+树是最佳的数据结构。对于单个选择,B-树可能更好(因为树的深度/大小),因为数据指针也位于树内部。

首先,也是最重要的,如果您没有使用InnoDB,请关闭此问题,使用InnoDB重建,然后查看是否需要重新打开问题。MyISAM不是首选,不应讨论

您是如何在MySQL中构建索引的?有几种方法可以显式或隐式地构建索引;它们会导致包装的好坏

MySQL:数据和索引存储在由16KB块组成的B+树中

MySQL:
唯一
索引(包括
主键
必须在插入行时更新。因此,一个
唯一的
索引必然会有很多块分割,等等

MySQL:
主键
与数据聚集在一起,因此它实际上占用了零空间。如果按主键顺序加载数据,则块碎片最小

非唯一次键可能会动态生成,这会导致一些碎片。或者可以在加载表后构建它们;这将导致更密集的包装

辅助键(
UNIQUE
或not)隐式包含
主键。如果主键是“大的”,那么次键是大的。你的主键是什么?这是‘答案’吗

理论上,完全随机插入到BTree中会导致块的填充率约为69%。也许这就是答案。MySQL是否大45%(1/69%)

对于100M行,可能很多操作都是I/O绑定的,因为您没有足够的RAM来缓存所有需要的数据和/或索引块。如果夏娃