用于内存算法的 Colstore 与 Rowstore
Colstore vs Rowstore for in-memory algorithms
我熟悉使用列存储与行存储来了解数据库如何在内部将数据持久保存到磁盘。我的问题是,对于一个数据集完全在内存中,并且没有存储到磁盘,行方向与列方向是否有很大的不同?
我能想到的可能会有所作为的事情是:
- 对于 8 字节以下的字段,与行相比,列涉及的内存访问更少。
- 无论是否在内存中,列存储上的压缩也会更容易(我想如果不保存回存储似乎不是问题?压缩对内存操作有影响吗?)
- 可以向量化操作。
- 当然,使用
struct
逐行处理要容易得多。
这两个都准确吗,还有更多吗?鉴于此,在只读数据集上使用内存中的 colstore 与 rowstore 相比,性能会得到实质性改进,还是只是边际改进?
对于内存数组,这称为 AoS vs SoA(结构数组与数组结构)。
我认为 SoA 对于只读数据库的主要优势是搜索需要访问更小的内存范围。这对缓存更友好,更不容易出现页面错误。
改进的程度取决于您如何使用数据库。通过使用更有针对性的结构(排序数组、B 树)可能会有一些更显着的改进
I'm familiar with using a column- vs a row-store for how a databases internally persists data to disk. My question is whether, for a dataset is entirely in memory, and there's no storage to disk, if the row- vs column- orientation makes much of a difference?
很大程度上取决于数据集的大小、每行的内容、您需要如何在其中进行搜索、是否要向数据集中添加项目或从数据集中删除项目等等。
还有 CPU 和内存架构需要考虑;您的缓存有多大,缓存行的大小是多少,以及您的 CPU 的 prefetcher.
有多智能
For fields under 8 bytes, it would involve less memory accesses for columns than for rows.
内存不是一次访问一个寄存器,而是一次访问一个cache line。在大多数当代机器上,缓存行是 64 字节。
Compression would also be easier on a column-store regardless of whether in memory or not
不是真的。您可以 compress/decompress 一个列,即使它没有连续存储在内存中。不过它可能 更快 。
does compression ever matter on in-memory operations?
这取决于。如果它在内存中,那么压缩可能会降低性能,但另一方面,您需要存储的数据量较小,因此您将能够将更多内容放入内存中。
Possible to vectorize operations.
只是 loading/storing 如果数据按行分组,内存可能会变慢。
Much, much easier to work with a struct on a row-by-row basis of course.
在逐行存储中使用指向 struct
的指针很容易,但是使用 C++ 可以使 类 隐藏数据按列存储的事实柱子。这在前面需要做更多的工作,但是一旦你设置好它可能会像逐行一样简单。
此外,entity-component-system pattern, and there are libraries such as EnTT 中经常使用逐列存储,这使得它非常容易使用。
Are both of those accurate, and are there any more? Given this, would there be substantial performance improvements on using an in-memory colstore vs rowstore on a read-only dataset, or just a marginal improvement?
同样,这在很大程度上取决于数据集的大小以及您希望如何访问它。如果您经常使用一行中的所有列,则首选逐行存储。如果您经常只使用一列,并且需要访问许多连续行的该列,那么最好是逐列存储。
此外,还有可能的混合解决方案。您可以单独拥有一列,然后以逐行方式存储所有其他列。
如何在只读数据集中进行搜索非常重要。它会被排序,还是更像一个哈希映射?在前一种情况下,您希望索引尽可能紧凑,并且可能像 B-tree 一样排序,正如 Alex Guteniev 已经提到的那样。如果它要像哈希映射,那么您可能需要逐行。
我熟悉使用列存储与行存储来了解数据库如何在内部将数据持久保存到磁盘。我的问题是,对于一个数据集完全在内存中,并且没有存储到磁盘,行方向与列方向是否有很大的不同?
我能想到的可能会有所作为的事情是:
- 对于 8 字节以下的字段,与行相比,列涉及的内存访问更少。
- 无论是否在内存中,列存储上的压缩也会更容易(我想如果不保存回存储似乎不是问题?压缩对内存操作有影响吗?)
- 可以向量化操作。
- 当然,使用
struct
逐行处理要容易得多。
这两个都准确吗,还有更多吗?鉴于此,在只读数据集上使用内存中的 colstore 与 rowstore 相比,性能会得到实质性改进,还是只是边际改进?
对于内存数组,这称为 AoS vs SoA(结构数组与数组结构)。
我认为 SoA 对于只读数据库的主要优势是搜索需要访问更小的内存范围。这对缓存更友好,更不容易出现页面错误。
改进的程度取决于您如何使用数据库。通过使用更有针对性的结构(排序数组、B 树)可能会有一些更显着的改进
I'm familiar with using a column- vs a row-store for how a databases internally persists data to disk. My question is whether, for a dataset is entirely in memory, and there's no storage to disk, if the row- vs column- orientation makes much of a difference?
很大程度上取决于数据集的大小、每行的内容、您需要如何在其中进行搜索、是否要向数据集中添加项目或从数据集中删除项目等等。
还有 CPU 和内存架构需要考虑;您的缓存有多大,缓存行的大小是多少,以及您的 CPU 的 prefetcher.
有多智能For fields under 8 bytes, it would involve less memory accesses for columns than for rows.
内存不是一次访问一个寄存器,而是一次访问一个cache line。在大多数当代机器上,缓存行是 64 字节。
Compression would also be easier on a column-store regardless of whether in memory or not
不是真的。您可以 compress/decompress 一个列,即使它没有连续存储在内存中。不过它可能 更快 。
does compression ever matter on in-memory operations?
这取决于。如果它在内存中,那么压缩可能会降低性能,但另一方面,您需要存储的数据量较小,因此您将能够将更多内容放入内存中。
Possible to vectorize operations.
只是 loading/storing 如果数据按行分组,内存可能会变慢。
Much, much easier to work with a struct on a row-by-row basis of course.
在逐行存储中使用指向 struct
的指针很容易,但是使用 C++ 可以使 类 隐藏数据按列存储的事实柱子。这在前面需要做更多的工作,但是一旦你设置好它可能会像逐行一样简单。
此外,entity-component-system pattern, and there are libraries such as EnTT 中经常使用逐列存储,这使得它非常容易使用。
Are both of those accurate, and are there any more? Given this, would there be substantial performance improvements on using an in-memory colstore vs rowstore on a read-only dataset, or just a marginal improvement?
同样,这在很大程度上取决于数据集的大小以及您希望如何访问它。如果您经常使用一行中的所有列,则首选逐行存储。如果您经常只使用一列,并且需要访问许多连续行的该列,那么最好是逐列存储。
此外,还有可能的混合解决方案。您可以单独拥有一列,然后以逐行方式存储所有其他列。
如何在只读数据集中进行搜索非常重要。它会被排序,还是更像一个哈希映射?在前一种情况下,您希望索引尽可能紧凑,并且可能像 B-tree 一样排序,正如 Alex Guteniev 已经提到的那样。如果它要像哈希映射,那么您可能需要逐行。