HANA的SQL优化器分为两种,基于规则优化(Rule based optimization)和基于成本优化(Cost based optimization)。先执行基于规则优化,然后执行基于成本优化。 规则优化是一个串行的优化过程,而成本优化是在规则优化之后,并发多种可能并记录最优的那个。基于规则优化是宏观层面的,容易预测到的。而基于成本优化更像是微观层面,会充满变化。
基于规则的优化将会基于HANA内置的优化规则重写整个执行树,比较经典的比如:
基于成本的优化会并发分析并比较执行成本,成本是用样本计算得到的,样本大小一般是指样本条目数(使用参数compile_time_sampling_size控制,默认值为1000),也有可能因为数据类型和特殊运算而发生变化。
比如:一个百万条目的表,如果存在数据格式为DOUBLE或者TEXT的列,并且会涉及到ROW_NUMBER或RANK这样的窗口函数,优化器就会尝试下放过滤器来尽可能减少中间表的大小,避免在大量数据上执行窗口函数。
SQL优化的最终目的是缩短执行时间,而当试图得到最优的SQL执行计划时,会对CPU和内存造成额外的负载。所以需要对时间资源和空间资源做好平衡。(比如提高sampling size,会提高找到更优路线的机会,同时也会更加消耗CPU与内存)
基于成本的优化采用枚举的方式寻找最优解,分为两种方式:逻辑枚举与物理枚举。
逻辑枚举是对QO树(query optimizer tree)的树型进行各种调整的尝试,比如交换JOIN和聚合的执行顺序,交换JOIN和FILTER(where)的顺序等等。
常见的两种模式:
A_THRU_B: JOIN_THRU_JOIN, JOIN_THRU_AGGR, LIMIT_THRU_JOIN等,是指执行顺序的交换,去看这些顺序变化是否能够缩短执行时间。
PRE_A_BEFORE_B: 最主要是PREAGGR_BEFORE_JOIN,在JOIN之前,预先聚合一部分数据,以减少JOIN的数据量。
逻辑枚举的关注点在FILTER,JOIN,AGGREGATION这些操作的顺序,而物理枚举的关注点在执行引擎的选择,执行的位置等。
选择执行引擎:在语句中指定行引擎或者列引擎是没有用的,因为物理枚举会都试一遍,找到最快的引擎。
执行位置(本地或远程):这一条指的是当HANA作为远程连接时(Smart Data Access,Near Line Storage,Dynamic Tiering),考虑一条语句是在远程库执行还是拿到HANA执行。在这种情况下考虑优化时,尤其需要考虑远端数据库的资源,链路传输速度等问题。