宝塔山 发表于 2024-1-17 08:34:10

聊聊分布式 SQL 数据库Doris(八)

稀疏索引

密集索引:文件中的每个搜索码值都对应一个索引值,就是叶子节点保存了整行.
稀疏索引:文件只为索引码的某些值建立索引项.
稀疏索引的创建过程包括将集合中的元素分段,并给每个分段中的最小元素创建索引。在搜索时,先定位到第一个大于搜索值的索引的前一个索引,然后从该索引所在的分段中从前向后顺序遍历,直到找到该搜索值的元素或第一个大于该搜索值的元素。
Doris中的前缀索引、Bloom Filter属于稀疏索引.
以mysql为例,主键索引是稠密索引; 非主键索引(非聚簇索引)是稀疏索引. 如下是mysql的B+树索引结构图.
主键索引, 注意叶子节点的主键值时有序的.
https://img2020.cnblogs.com/blog/1546632/202008/1546632-20200830201413134-394816073.png
非主键索引
https://img2020.cnblogs.com/blog/1546632/202009/1546632-20200919225813936-1490118290.png
联合索引
https://img2020.cnblogs.com/blog/1546632/202009/1546632-20200920111026527-1672463564.png
稀疏索引占用空间少,但是在查询的精确率上还是相对于稠密索引还是比较慢的,因为不需要顺序查找,还有回表。
稠密索引那就是相对来说比较快,因为他可以精确定位数据,但是占用的空间比较大。
参考:
密集索引和稀疏索引
一文读懂MySQL的索引结构及查询优化
delete

delete: 本质上是存储了一个删除条件,在查询时会对每一行记录应用这个删除条件做过滤,因此当有大量删除条件时,查询效率就会降低。
批量删除: 仅适用于 UNIQUE KEY 模型,解决了delete大批量数据的性能问题; Doris内部会增加一个隐藏列__DORIS_DELETE_SIGN__. 该列的类型为bool,聚合函数为replace. 在导入与读取时,增加隐藏列的判断,筛选过滤掉不必要的数据.
参考:
数据删除
批量删除
更新

Doris中存储的数据都是以追加(Append)的方式进入系统,这意味着所有已写入的数据是不可变更(immutable)的。所以Doris采用标记的方式来实现数据更新的目的; 利用查询引擎自身的 where 过滤逻辑,从待更新表中筛选出需要被更新(被标记)的行。再利用 Unique 模型自带的 Value 列新数据替换旧数据的逻辑,将待更新的行变更后,再重新插入到表中,从而实现行级别更新。
适用场景

[*]对满足某些条件的行,修改其取值;
[*]点更新,小范围更新,待更新的行最好是整个表的非常小的一部分;因为大批量数据下整行更新,会导致性能较低。
[*]update 命令只能在 Unique 数据模型的表中执行;因为只有该模型可以保证主键的唯一性,从而支持按主键对数据进行更新。
假设 Doris 中存在一张订单表,其中 订单id 是 Key 列,订单状态,订单金额是 Value 列。数据状态如下:
订单订单金额订单状态1100待付款这时候,用户点击付款后,Doris 系统需要将订单id 为 '1' 的订单状态变更为 '待发货',就需要用到 Update 功能。
UPDATE test_order SET order_status = '待发货' WHERE order_id = 1;更新结果如下:
订单订单金额订单状态1100待发货用户执行 UPDATE 命令后,系统会进行如下三步:

[*]第一步:读取满足 WHERE 订单id=1 的行 (1,100,'待付款')
[*]第二步:变更该行的订单状态,从'待付款'改为'待发货' (1,100,'待发货')
[*]第三步:将更新后的行再插入原表中,从而达到更新的效果。
订单订单金额订单状态1100待付款1100待发货由于表 test_order 是 UNIQUE 模型,所以相同 Key 的行,之后后者才会生效,所以最终效果如下:
订单订单金额订单状态1100待发货部分列更新

Doris默认的更新是行更新. 列更新可以很大程度上提高写入与并发性能.
Unique Key模型的Merge-on-Write结合MVCC支持部分列更新.
Aggregate Key模型将聚合函数设置为REPLACE_IF_NOT_NULL支持部分列更新.
更新原理

Unique Key模型的列更新实现:用户通过正常的导入方式将一部分列的数据写入Doris的Memtable,此时Memtable中并没有整行数据,在Memtable下刷的时候,会查找历史数据,用历史数据补齐一整行,并写入数据文件中,同时将历史数据文件中相同key的数据行标记删除。
Aggregate Key模型,则是直接利用聚合函数筛选过滤。
使用建议:

[*]对写入性能要求较高,查询性能要求较低的用户,建议使用Aggregate Key模型
[*]对查询性能要求较高,对写入性能要求不高(例如数据的写入和更新基本都在凌晨低峰期完成),或者写入频率不高的用户,建议使用Unique Key模型merge-on-write实现
参考:
数据更新

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 聊聊分布式 SQL 数据库Doris(八)