一、背景
列式存储是目前广泛应用于各种分析型数据库、或者存储格式中;其中数据库比如 hbase、clickhouse、doris;数据文件包括parquet,orc;今天,就来总结一下列式存储相对于行式存储优缺点;
二、列式存储与行存储的优缺点
2.1 列式存储
- 并发:查询过程中可以并发针对各列计算、过滤,查询过程中竟可能最后才合并成完整的记录,最大可能的降低查询时间
- 存储:
- 列式存储的数据更加有规律,压缩效果好,减少磁盘IO;(压缩算法通常在比较有规律的数据上表现优异,比如长度,类型一致,对于每一条数据都不相同的情况下,表现较差)
- 列式存储在查询时可以减少无关列的IO;
- 列式存储在内存计算时,由于没有无关列的污染,所以缓存的cache命中率也会提升;
- 更新问题
- 列式存储将一列的数据分开存储,且通常不会用B+Tree作为索引;所以很难支持事务更新,频繁更新,实时更新;若硬要支持,则会降低查询分析的性能,得不偿失;
- 另外当,数据量少且属性少时,使用列式存储;由于列式存储的IO减少,并发提高带来的优势被抵消,所以不如直接使用行存储;
2.2 行存储
行存储一般以传统的数据库Mysql,Orical为代表;使用B+Tree作为主键索引;比较适用于以下场景:
- 需要随机的增删改查
- 需要频繁的插入更新
- 经常读取所有的属性
2.3 列式查询通常的优化技巧
2.3.1 延迟物化
如下图所示,延迟物化的意思是延迟将列式数据转化成行式数据的时间点,延迟物化有很多好处:
- 关系代数中的projection、aggregateion都会产生大量的Tuple -> Tuple的转换操作,如果延迟物化可以减少不必要的转换操作
- 物化必须要解压数据,压缩降低IO的优势没了
- Row中的一个属性不会被无关的属性干扰,操作系统的cache命中率提高
- 向量化执行更容易兼容列保存的数据
2.3.2 向量化执行
(vectoried query processing),批次执行,硬件层面加速;
2.3.3 压缩
高效的压缩可以减少磁盘IO数据量,但是高效的压缩都必须遵循某种特殊的规律,比如数据的长度,类型等一致;基于列式的查询数据库正好遵循这一点; 此外,某些特别的数据压缩格式,比如 RUN-Length编码,甚至可以在不做解压时便可以对数据过滤,减少无关的IO