列式存储 vs 行式存储:它们之间的本质区别在哪里?

原文

论文链接
Column-Stores vs. Row-Stores: How Different Are They Really?

列式存储与行式存储的区别
列式存储vs行式存储-1
列式存储vs行式存储-2

概述

该文发表在 2008 年的 SIGMOD 会议上。从论文标题可以看出,论文主要内容不是陈述一种新的技术、架构,而是偏向议论、验证。其主要目的在于阐述清楚在 OLAP 下为什么列式存储Column-Store优于行式存储Row-Store。

在 OLAP 场景下,基准测试的结论都是列式存储比行式存储快一个数量级。而大家普遍理解的原因是

column-stores are more I/O efficient for read-only queries since they only have to read from disk (or from memory) those attributes accessed by a query.

对于只读查询,列式存储的 I/O 效率更高,因为它们只需要从磁盘(或内存)中读取查询所需要的那些字段。

从这个理解出发,大家想到即使是行式存储,也可以通过一些优化手段达到列式存储的性能,包括:

  • 垂直分表Vertically Partitioning
  • 全列索引Indexing Every Column

简介

作者认为当年面向列的系统性能测试方面过于“传统”——仍然以面向行的系统数据结构的设计思路来设计性能测试方案。虽然看出了列式存储的潜力,但没有回答本质问题:

问题
Are these performance gains due to something fundamental about the way column-oriented DBMSs are internally architected, or would such gains also be possible in a conventional system that used a more column-oriented physical design?

列式存储带来的性能提升是由于它内部架构的基本原理导致的,还是采用更加面向列式物理设计的传统系统中也有可能实现这些性能提升?

为了验证这个问题,作者采用了垂直分表、索引查询Index-only Plans、物化视图Materialized Views三种设计范式来实现更加面向列式物理设计的行式系统:

  • 垂直分表,将表结构拆分为二元组的形式,来实现对于一个查询,只需要访问特定列的目标;
  • 索引查询,为每个表创建一组索引,以确保可以覆盖所有查询中所需要的列,保证查询过程中直接从索引中提取字段的值;
  • 物化视图,针对所有查询做物化视图,以获取最佳的查询性能。

经过模拟实验,作者得出结论,即使在面向行的系统中应用了面向列的思路来设计存储范式,在分析场景下,性能仍然无法与面向列的系统抗衡。

在得到上述结论后,作者又抛出下一个问题:

问题
Which of the many column-database specific optimizations proposed in the literature are most responsible for the significant performance advantage of column-stores over row-stores on warehouse workloads?

在数仓场景下,究竟是哪些优化手段让面向列的系统性能优于面向行的系统性能?

论文直接给出结论,面向列的系统中优化主要有:

  • 延迟物化Late Materialization
  • 块遍历Block Iteration
  • 压缩Compression
  • 隐式连接Invisible Joins(本文创新优化点)

到这里,作者提出了第三个问题:

问题
However, because each of these techniques was described in a separate research paper, no work has analyzed exactly which of these gains are most significant.

定量来看,这几种优化手段分别可以为面向列的系统提升多少性能呢?

接下来的工作中,作者逐个移除 C-Store 数据库中的上述优化手段来进行测试,最终发现:

  • 压缩带来的性能提升要看具体的数据,最多时可以提升一个数量级
  • 延迟物化可以提升 3 倍
  • 块遍历和隐式连接可以提升约 1.5 倍

面向列的执行

压缩

压缩,就是将相似度很高、信息熵很低的数据放在一起,用更小的空间表达相同的信息量。列存的数据往往类型相同,相同的特征更多,更容易被压缩,所以列存系统的压缩优化比行存系统更加有效。
压缩优化带来的优势有:

  • 压缩后的数据量更小,可以减少硬盘存储空间,同时硬盘的数据量变少在读取时就可以减少 I/O 压力;

  • 有些时候解压缩的过程可以省略掉,从而直接对压缩后的数据进行操作。比如使用 Run-Length 编码方式进行压缩的数据,就可以直接进行某些运算。

      Run-Length 压缩
      
          对于原始序列为 1, 1, 2, 2, 3, 3, 3 的数据,压缩后表达为 1 * 2,  2 * 2, 3 * 3。当我们要对这一列进行 sum 或者 count 运算时,原始数据可以直接转换为 $sum(1 * 2 + 2 * 2 + 3 * 3) $ 和 $ count(2 + 2 + 3)$,不仅不需要解压缩,而且还提高了计算效率。
    

另外,压缩优化最好可以配合 sort 使用,如果数据是经过排序的,则更容易找到相邻数据的同质化特征,获得更好的压缩效果。

延迟物化

Materialization 物化 是指为了把底层面向列的存储格式跟要求的行式格式对上,需要在查询的某个阶段转换一下。在这里插入图片描述
理解物化的概念后,延迟物化就很好理解了,意思就是把物化的时机尽量地拖延到整个查询声明的后期。延迟物化意味着在查询执行的前一段时间内,查询执行的模型不是关系代数,而是基于 Column 的。

总结

读这篇论文最大的收获是首先明确了是哪些因素促使列式存储对 OLAP 性能可以大幅提升——压缩、延迟物化、块遍历、隐式连接。

论文三位作者系统系统解答了列式存储与行式存储的区别,通过实验告诉我们,列式存储是因为其内部架构而具有更好的性能,而不是理所当然的理由——更少的 I/O。不仅仅限于内部架构,查询引擎层的各种优化也同样是列式存储性能提升的关键。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简放视野

深度思考,简放视野

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值