分区表对导入操作的性能影响
在GaussDB中,相较于非分区表,分区表在数据插入处理流程中额外增加了分区路由环节的开销。
所以从整体来看,分区表场景下的数据插入开销主要由两部分构成,如图1所示:(1)heap-insert基表插入:此部分负责解决元组(tuple)存入对应堆表(heap表)的问题,并且这一操作在普通表和分区表中是通用的;(2)partition-routing分区路由:该部分主要解决分区路由问题,也就是要将元组插入到对应的分区表(partRel)中,并且分区路由算法本身作为一级、二级分区共用,不同之处在于二级分区相比一级分区多一层路由操作,对路由算法为两次调用。
- 分区表基表Heap表插入:
- 算子底噪优化。
- heap数据插入。
- 索引插入build优化(带索引)。
- 分区表分区路由:
- 路由查找算法逻辑优化。
- 路由底噪优化,包括分区表partRel句柄开启、新增的函数调用逻辑开销。
分区路由的性能在大数据量的单条INSERT语句执行时能得到显著体现。而在UPDATE场景中,其内部操作逻辑更为复杂,它需要先查找出对应要更新的元组,执行DELETE操作将其移除,之后再执行INSERT操作插入新的元组。相较于单条INSERT语句直接插入数据的场景,UPDATE场景的操作步骤更多,流程更繁琐,所以分区路由性能在UPDATE场景下的体现不如单条INSERT语句场景直接。
| 分区方式 | 路由算法复杂度 | 实现概述说明 |
|---|---|---|
| 范围分区(Range Partition) | O(logN) | 基于二分binary-search实现。 |
| 间隔分区(Interval Partition) | O(logN) | 基于二分binary-search实现。 |
| 哈希分区(Hash-Partition) | O(1) | 基于key-partoid哈希表实现。 |
| 列表分区(List-Partition) | O(1) | 基于key-partoid哈希表实现。 |
| 二级分区(List/List) | O(1) + O(1) | 哈希+哈希。 |
| 二级分区(List/Range) | O(1) + O(1) = O(1) | 哈希+二分查找。 |
| 二级分区(List/Hash) | O(1) + O(1) = O(1) | 哈希+哈希。 |
| 二级分区(Range/List) | O(1) + O(1) = O(1) | 二分查找+哈希。 |
| 二级分区(Range/Range) | O(1) + O(1) = O(1) | 二分查找+二分查找。 |
| 二级分区(Range/Hash) | O(1) + O(1) = O(1) | 二分查找+哈希。 |
| 二级分区(Hash/List) | O(1) + O(1) = O(1) | 哈希+哈希。 |
| 二级分区(Hash/Range) | O(1) + O(1) = O(1) | 哈希+二分查找。 |
| 二级分区(Hash/Hash) | O(1) + O(1) = O(1) | 哈希+哈希。 |
- x86服务器场景下一级分区表相比普通表的导入性能会略低10%以内,二级分区表比普通表略低20%以内。
- ARM服务器场景下为20%、30%,造成x86和ARM指向性能略微差异的主要原因是分区路由为in-memory计算强化场景,主流x86体系CPU在单核指令处理能力上略优于ARM。
