CBO代价解析
在过去数据库主要使用基于规则的优化器(RBO),基于规则将SQL解析生成的关系表达式进行等价交换,形成更优的方案,例如,有一个多表查询SQL
select a.c_id,sum(c.price) from a,b,c where a.c_id=c.c_id and c.o_id=b.o_id group by a.c_id order by sum(c.price) desc;
如果直接解析,将会把a,b,c查询的一部分创建为CROSS JOINS,再创建FILTER。再未优化的情况下,CROSS JOINS将产生大量的中间数据。即使试图执行这样的计划也没有意义。
取而代之,利用RBO规则引擎,将会把cross join修改成按key进行两表连接的方式。确实会比CROSS JOINS更好。
同样的表连接,将大表放入内存和将小表放入内存明显会有效率上的差异,但给予规则,此类设计会很复杂。
而基于CBO,将会明显提升效率。所以在数据库的CBO设计中,主要参考了传统关系型数据库,将CPU时间、内存需求和网络带宽使用率作为三个影响查询执行效率的三个维度。
在数据库中记为成本。同时根据表的内部统计信息,在逻辑计划转换成物理计划时,派生多个不同的物理计划,并对每个物理计划进行评价,估计实现这个转换的代价。除枚举外同时考虑使用动态规划算法。
考虑有多个查询同时进行,每个查询的成本不同,如何做到更高并发的查询计划,需要进行权衡,这基本意味着需要以尽可能少的资源尽可能快地执行查询。在数据库中,使用成本概念进行建模,捕获例如CPU成本、内存需求和网络带宽使用率之类的属性,探索查询执行计划的不同变体,分配成本并进行比较,选择总成本最低的变体执行。这种方法巧妙地平衡了集群对于查询响应速度、高并发等需求。
在查询计划中,每项操作的成本均以适合于该操作类型的计算方式及该操作涉及的数据统计信息进行计算。
path
查询执行计划的拆分汇总
表扫描(读取表;运行时与过滤器结合使用)、过滤器(SQL的where子句或查询计划程序推断出的任何其他条件)、投影(计算输出表达式)、JOIN、聚合、排序(ORDER BY)、限制(LIMIT等)、排序和限制组合(例如order by limit)、其他。
表扫描统计。
表从读取数据的任何过滤条件的使用,例如表中如果存在分区,过滤条件排除掉某些分区后,则统计信息将考虑使用更小的数据集,并且更加准确。
过滤统计。
在进行过滤操作时将分析过滤条件,并计算估算值,包括以下:数据行通过过滤条件的概率(得到过滤器之后的预期行数);过滤条件涉及的列的不同值的数量;不属于过滤条件的列的不同值的数量(如果原始不同值数量大于通过过滤器的数据行的预期数量),理想状态下,估算值=输入行数*非空值分数/去重值。
投影统计。
按关系型理论考虑投影,投影的结果大小是可精确计算的,通常,投影与过滤器类似,不同之处在于,投影不会影响操作后的预期行数,对于投影,将计算以下类型的列统计信息:投影产生不同值的数量,NULL投影产生的值,投影产生的最小值/最大值。如果投影表达式是直接返回的,则无需统计。如果是将其作为过滤器或连接操作时,则这些统计信息对于正确估计过滤器条件或连接返回的行数很重要。
CBO从概念上来说是简单的,流程上考虑替代查询计划,选择并执行最佳计划,但细节上比传统关系型数据库需要考虑的更多,传统数据库基本只需要考虑磁盘IO即可。
在未使用CBO优化器前,针对1TB数据量的TPC-DS数据,在查询某些SQL时(如query72),需要至少三个小时或以上才可以出结果,而在增加CBO优化器后,进行查询将时间缩短到了5分钟左右,效率整整提升了至少10倍到100倍。
以上为基于代价解析的最优路径规划,「分布式技术专题」是国产数据库hubble团队精心整编,专题会持续更新,欢迎大家保持关注。