Colstore vs Rowstore用于内存算法



我熟悉使用列存储和行存储来了解数据库如何在内部将数据持久化到磁盘。我的问题是,对于一个数据集是否完全在内存中,并且没有存储到磁盘,如果行与列的方向有很大的不同?

我能想到的可能有所不同的事情是:

  • 对于8字节以下的字段,列的内存访问要比行少。
  • 压缩在列存储上也更容易,无论是否在内存中(如果不保存回存储,我想似乎不是问题)?压缩对内存操作有影响吗?)
  • 可以进行矢量化操作。
  • 当然,在逐行基础上使用struct要容易得多。

这两个都是准确的吗,还有其他的吗?考虑到这一点,在只读数据集上使用内存colstore和行存储是否会有实质性的性能改进,或者只是边际改进?

对于数据库如何在内部将数据持久化到磁盘上使用列存储和行存储,我很熟悉。我的问题是,对于一个数据集是完全在内存中,并没有存储到磁盘,如果行- vs列方向的区别?

这在很大程度上取决于数据集的大小,每行的内容是什么,您需要如何在其中搜索,是否要向数据集添加项或从数据集删除项,等等。

还需要考虑CPU和内存架构;你的缓存有多大,缓存线的大小是多少,你的CPU的预取器有多智能。

对于小于8字节的字段,列的内存访问比行要少。

内存不是一次访问一个寄存器,而是一次访问一个缓存行。在大多数现代机器上,缓存行是64字节。

无论是否在内存中,在列存储上压缩也更容易

没有。即使列不是连续存储在内存中,也可以压缩/解压缩列。可能更快

压缩对内存操作有影响吗?

,视情况而定。如果它在内存中,那么压缩可能会降低性能,但另一方面,您需要存储的数据量更小,因此您将能够在内存中容纳更多数据。

可以进行矢量化操作。

它只是加载/存储到内存中,如果数据按行分组可能会更慢。

当然,在逐行基础上使用结构体要容易得多。

使用指向struct的指针进行逐行存储是很容易的,但是在c++中,您可以创建类来隐藏数据逐列存储的事实。这有点更多的工作,但可能会使它容易逐行一旦你把它支起来。

此外,逐列存储通常用于实体-组件-系统模式,并且有诸如EnTT之类的库使其非常容易使用。

这两个都是准确的吗,还有其他的吗?考虑到这一点,在只读数据集上使用内存colstore和行存储是否会有实质性的性能改进,或者只是边际改进?

同样,这在很大程度上取决于数据集的大小以及您希望如何访问它。如果经常使用一行中的所有列,则首选逐行存储。如果您经常只使用一列,并且需要访问由许多连续行组成的列,那么逐列存储是最好的选择。

也有混合动力解决方案成为可能。您可以单独拥有一列,然后以逐行方式存储所有其他列。

如何在只读数据集中搜索非常重要。它会被排序吗,还是更像一个哈希映射?在前一种情况下,您希望索引尽可能紧凑,并且可能像Alex Guteniev已经提到的b树那样有序。如果它像散列映射一样,那么您可能需要逐行。

对于内存数组,这称为AoS vs SoA(结构体数组vs数组结构体)。

我认为SoA对于只读数据库的主要优势是搜索将需要访问更小的内存范围。这对缓存更友好,更不容易出现页面错误。

改进的量取决于您如何使用数据库。如果使用更有针对性的结构(排序数组,B-tree),可能会有更显著的改进

最新更新