如何从列式数据库中读取编码数据,例如在Vertica中进行RLE编码数据?

时间:2017-03-02 09:47:12

标签: database vertica columnstore

在下表中,当Dept字段中的数据被编码和存储时,值为10的Dept如何知道它的Age值为38.

ID部门年龄

1 10 60

2 10 38

3 10 49

对于行商店,我理解我检查ID 2,我得到整行的数据。

但是当我在柱状存储和Dept信息处于编码形式时,我无法理解如何为ID 2检索数据。

如果我错过了一些明显的东西,你能帮我理解吗?

3 个答案:

答案 0 :(得分:2)

首先,让我们以未编码的形式考虑柱状数据:

值为2的

ID是列中的第二个元素,因此要获取DeptAge所有需要完成的操作,请使用第二个元素。

现在以编码(压缩)形式,您可以查看范围中的数据。例如,Dept可以编码为3 * 10,因此范围1-3的值为10.要检索Dept中的第二个元素,数据库必须查找包含第二个元素的范围元件。这将是范围1-3,其值为10.

或者以另一种方式看待:以顺序的方式获得位置4的Dept,系统会看到有一组3个元素压缩成1个值,所以该组之后的项目(可能是一组新的相同值)将包含第四个元素的值。

为了加快速度,系统当然会保留一个位置索引,以便能够直接跳转(半)到某个范围的值(这些范围/组将存储在块中,比如1-8例如,每个 - 例如B+ Tree,特别是当需要稍后插入值时。)

另一种可能性是将这些组(带有rle前缀的范围值)存储在块中,跟踪每个块的第一个和(或唯一的)最后一个项索引,并解压缩包含索引值的块我们正在寻找。然后计算该解压缩块中项目的偏移量。这取决于用于在该块中存储数据的压缩类型。

另一方面,在大多数情况下,我们不需要记录中的所有数据,这就是基于列的数据存储如此有趣的原因。

让我们考虑一个包含10亿条记录,每条200字节(字符串数据等)的表和一个具有10 GB可用RAM的系统(我记录的数量足够大,因此表格不适合内存)。这就是200 GB的数据。

现在假设我们想要某个列的总和(一个4字节的整数列)。要计算基于记录的表的总和,我们必须每200字节读取一次值,并且由于数据是从4kB页面的磁盘读取的,因此我们必须读取完整的200GB。在100MB /秒的普通磁盘上需要2000秒。

如果我们将数据分成列,即使使用未压缩的数据,我们也只需读取4GB的数据(可能已经在内存中)。如果列被压缩,比如10:1,则只有400MB。如果数据稀疏(比如很多零或空值),那就更少了。另外,为了对100个相同值进行求和,所有需要做的就是100 *值而不是从磁盘读取100 * 200个字节,或者如果它们为零则跳过该范围。

还有一个额外的速度增益,因为所有数据(所有值都在一起)将从L1 CPU缓存访问,这比访问主内存要快得多。

答案 1 :(得分:1)

这里没有什么可以理解的!数据表示与Vertica将数据写入FS的方式无关。

编码用于优化数据获取过程。

对于基于行的vsarar,ROWKEY(内部数据库)的概念对两者都是一样的  ROWKEY由您的数据库引擎维护,“它以神秘的方式工作”:)

我短编码是写& amp;看,你不会看到编码的二进制代码,你将看到编码数据的表示。

答案 2 :(得分:0)

首先:Vertica使用了许多不同的encoding types。 RLE只是可能的选项之一(适用于低基数,排序列)。请记住,某些编码可以减少存储大小(很多),但会增加CPU使用率。

第二次:如果你想看到" RLE在行动"请查看手册的this other section,提供清晰简洁的解释(我认为图片有很多帮助)。

第三次:在您的示例表中,选择正确的编码 - 就存储而言 - 非常简单。例如,如果对前两列进行排序,我会说第一列为COMMONDELTA_COMP,第二列为RLE。但是 - 一般来说 - 当您拥有大量数据时,您可能希望使用Vertica的数据库设计器自动选择"权利"编码...