openGauss在代码里面实现了大量的算子级优化工作,为了更进一步便于用户理解,我们对这些工作进行了总结,并且对内部具体的一些算法进行详细介绍,其总结如下。
【索引扫描算子优化】
对索引扫描算子进行了一定程度的重构与优化,以提升算子性能。优化主要包括以下几个方面:
-
识别到程序中存在影响性能的噪点,对其进行屏蔽;
-
在现有执行流程下,为多数场景下的高频操作建立fast-path,以提高执行效率;
-
对一些数据结构与算法的实现进行了优化重构,以提升性能。最终经过测试,IndexScan算子性能提升10%,IndexOnlyScan算子性能提升30%。
【函数依赖】
函数依赖,是多列统计信息的一种,可以描述属性之间的关联关系,其主要用途是提高选择率估算的准确性。在引用函数依赖特性之前,数据库会使用条件独立假设的方法来估算选择率。举一个生活中的例子,在一个班级中,男女生的比例是1:1,喜欢瑜伽的人数占比为20%,身高175cm以下的人数占比为50%。我们可以说喜欢瑜伽且身高在175cm以下的女生的占比为50% * 20% * 50% = 5%吗?显然这个计算结果会比实际结果略低,因为这几个属性之间有关联关系,喜欢瑜伽的人中女生占多数,女生的身高较男生普遍偏低。函数依赖特性就是用于解决此类问题,在典型场景下对于高频数据的查询,选择率提升20%;对于中频数据的查询,选择率提升10倍;对于典型场景,选择率提升70倍。
【AGG函数共享转移状态】
AGG函数的执行分为3个阶段:初始化转移状态、执行transition函数、执行final函数。AGG函数共享转移状态特性目的在于调整转移状态和transition函数,实现资源共享。例如执行”SELECT avg(a), sum(a) FROM t;”,此时的转移状态初始化后为两个参数(total, count),然后遍历表的所有元组,total执行累加操作,count执行自增操作,最后把total/count和total分别作为avg函数和sum函数的返回结果。经验证,SQL语句”SELECT avg(a), sum(a) FROM t;”的总耗时缩短48%左右。对其他可以共享转移状态的AGG函数,也可以实现不同程度的性能提升。
【Parser优化】
优化Parser阶段中关键字检查模块,将关键字查找算法由原来的二分查找算法优化为哈希查找算法,同时优化关键字内存数据结构,cache访问更友好,优化后Parser阶段的性能提升10%。
【新型选择率模型】
新型选择率模型充分利用基于直方图的统计信息,平衡计算量与准确性,充分考虑数据分布情况,通过轻量的计算,提高对低频值的估算准确率,能够使得优化器生成更优的执行计划,进而提高查询效率。
【通信优化】
提升通信整体性能,调整通信逻辑,默认使用非阻塞通信方式,当需要阻塞通信语义时,利用latch轻量锁机制,降低通信阶段耗时。轻量通信方式的开启与否通过POSTMASTER级别的GUC参数light_comm控制,当light_comm的值为ON / TRUE时,将开启轻量通信。
【表达式展平化】
基于非递归、操作码方式实现数据库中表达式计算,致力于通过展平化表达式信息减少计算过程中堆栈使用、函数调用等开销,提升语句的执行性能。
后续,openGauss还会持续对基础算子进行优化,不断完善openGauss社区竞争力。
openGauss: 一款高性能、高安全、高可靠的企业级开源关系型数据库。
🍒如果您觉得博主的文章还不错或者有帮助的话,请关注一下博主,如果三连收藏支持就更好啦!谢谢各位大佬给予的鼓励!