10.4.2 列式存储
列式存储主要的目的有两个:1)大部分OLAP查询只需要读取部分列而不是全部列数据,列式存储可以避免读取无用数据;2)将同一列的数据在物理上存放在一起,能够极大地提高数据压缩率。
列组(Column Group)
OceanBase通过列组支持行列混合存储,每个列组存储多个经常一起访问的列。
如图10-14所示,OceanBase SSTable首先按照列组存储,每个列组内部再按行存储。分为几种情况:
图 10-14 OceanBase列组设计
●所有列属于同一个列组。数据在SSTable中按行存储,OLTP应用往往配置为这种方式。
●每列对应一个列组。数据在SSTable中按列存储,这种方式在实际应用中比较少见。
●每个列组对应一行数据的部分列。数据在SSTable中按行列混合存储,OLAP应用往往配置为这种方式。
OceanBase还允许一个列属于多个列组,通过冗余存储这些列,能够提高访问性能。例如,某表格总共包含5列,用户经常一起访问(1,3,5)或者(1,2,3,4)列。如果将(1,3,5)和(1,2,3,4)存储到两个列组中,那么,大部分访问只需要读取一个列组,避免了多个列组的合并操作。
列式存储提高了数据压缩比,然而,实践过程中我们发现,由于OceanBase最初的几个版本内存操作实现得不够精细,例如数据结构设计不合理,数据在内存中膨胀很多倍,导致大查询的性能瓶颈集中在CPU,列式存储的优势完全没有发挥出来。这就告诉我们,列式存储的前提是设计好内存数据结构,把CPU操作优化好,否则,后续的工作都是无用功。为了更好地支持OLAP应用,新版的OceanBase将重新设计列式存储引擎。