渣渣兔 发表于 2024-9-1 15:50:00

列式存储详解

行式存储

传统的关系型数据库,如 Oracle、DB2、MySQL、SQL SERVER 等采用行式存储法(Row-based),在基于行式存储的数据库中, 数据是按照行为基础逻辑存储单元进行存储的, 一行中的数据在存储介质中以一连存储的情势存在。
适用场景:


[*]适合随机的增编削查操作;
[*]需要在行中选取全下属性的进行查询操作;
[*]对事件要求较高的系统;
[*]需要频繁插入或更新的操作,其操作与索引和行的大小更为干系
列式存储

列式存储(Column-based)是相对于行式存储来说的,比如:Hbase、Doris、Clickhouse等分布式数据库均采用列式存储。在基于列式存储的数据库中, 数据是按照列为基础逻辑存储单元进行存储的,一列中的数据在存储介质中以一连存储情势存在。
适用场景:


[*]在线分析处置惩罚系统(OLAP),如数据堆栈、商业智能(BI)系统、报表系统等
[*]大数据分析
[*]只读和数据归档,数据在写入后不常常修改,主要用于读取和分析
特点
行式存储
列式存储
存储结构
每行数据存储在一起
每列数据存储在一起
优点
快速插入、更新、删除操作
快速扫描和聚合操作
缺点
对大规模扫描和聚合操作倒霉
对频繁的插入、更新、删除操作倒霉
适用场景
OLTP系统、实时查询、复杂事件
OLAP系统、大数据分析、数据归档
 
行式数据库在读取数据的时间会存在一个固有的“缺陷”,比如,所选择查询的目标即使只涉及少数几项属性,但由于这些目标数据在各行数据单元中,而行单元往往又特别大,应用程序必须读取每一条完整的行记录,从而使得读取效率大大降低。对此,行式数据库给出的优化方案是加“索引”。在OLTP范例的应用中,通过索引机制或给表分区等手段,可以简化查询操作步骤,并提升查询效率。
但针对海量数据配景的OLAP应用(例如分布式数据库、数据堆栈等等),行式存储的数据库就有些吃力了,行式数据库创建索引和物化视图,需要花费大量时间和资源,因此还得不偿失,无法从根本上解决查询性能和维护成本等问题,也不适用于数据堆栈等应用场景,以是后来出现了基于列式存储的数据库。
对于数据堆栈和分布式数据库来说,大部分情况下它会从各个数据源汇总数据。然后进行分析和反馈。其操作大多是围绕同一列属性的数据进行的,而当查询某属性的数据记录时,列式数据库只需返回与列属性干系的值,在大数据量查询场景中,列式数据库可在内存中高效组装各列的值,终极形成关系记录集,因此可以显著减少IO消耗,并降低查询响应时间,非常适合数据堆栈和分布式的应用。
列式存储查询过程

1. 数据定位

首先,列式存储引擎会根据查询条件定位需要读取的列。例如,查询 SELECT Name, Salary FROM employees WHERE Age > 30。
2. 读取所需列

引擎只读取 Name 和 Salary 列的数据,不读取其他列。这显著减少了读取的数据量,进步了查询效率。
3. 应用查询条件

引擎应用查询条件 Age > 30,仅筛选出符合条件的行。例如,在列式存储中,读取 Age 列并找到满足条件的行号(或偏移量)。
4. 归并结果

引擎将读取到的数据按照查询条件进行归并,返回终极结果。

列式存储高效的关键点

有几大关键的优化点:


[*]向量化查询处置惩罚(vectorized query processing)、
[*]压缩(compression)、
[*]隐式连接(invisible join)、
[*]延迟物化(late materialization)
延迟物化

要理解延迟物化(Late Materialization), 首先解释一下什么是物化:为了能够把底层存储格式(面向Column的), 跟用户查询表达的意思(Row)对应上,在一个查询的生命周期的某个时间点,一定要把数据转换成Row的情势,这在Column-Store内里被称为物化(Materization)。
物化的机遇只管的拖延到整个查询生命周期的后期。
压缩技术

列式存储通常使用高效的压缩算法,由于同一列的数据范例相同,重复数据较多,压缩率高,
数据占用的硬盘空间越小,查询引擎花在IO上的时间就越少(不管是从硬盘内里把数据读入内存,还是从内存内里把数据读入CPU)。同时要记着的是数据压缩之后,要进行处置惩罚许多时间要需要解压缩(不管是Column-Store还是Row-Store), 因此压缩比不是我们追求的唯一,由于反面解压也需要花时间,因此一般会在压缩比息争压速度之间做一个权衡。
向量化查询

向量化查询引擎处置惩罚多个数据元素,可以使用 CPU 指令会合的 SIMD(Single Instruction, Multiple Data)特性,大幅提升查询速度。


有一点不太理解:age列是单独存储的,当查询Age > 30时,会在age列上查询,那如何对其他列如name、salary根据age做筛选查询的?
答:
在列式存储中,固然每一列的数据是单独存储的,但列与列之间的数据是通过相同的行索引(或行号)关联在一起的。查询过程中,数据引擎会使用这些行索引来归并结果。下面是具体的步骤解释,说明如安在列式存储中根据一个列的条件(如 Age > 30)筛选其他列(如 Name 和 Salary)。

[*] 扫描条件列: 首先,扫描条件列 Age。在列式存储中,这一列的数据是一连存储的,因此可以高效地进行扫描。例如,找到全部 Age > 30 的行。
[*] 获取匹配行的索引: 记录全部满足条件的行的索引(或行号)。例如,假如第 1 和第 3 行的 Age 大于 30,则记录这些行号 。
[*] 扫描目标列: 然后,扫描目标列 Name 和 Salary。同样,这些列的数据是一连存储的。
[*] 应用行索引过滤: 使用前面记录的行索引,从 Name 和 Salary 列中提取对应的行数据。例如,提取 Name 和 Salary 中第 1 和第 3 行的数据。
[*] 归并结果: 最后,将提取的数据归并成终极的结果集。









 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 列式存储详解