全部产品
云市场

查询改写与下推

更新时间:2019-11-20 17:19:50

下推是查询改写的一项重要优化,它可以利用DRDS的拆分信息来优化执行计划,使得算子尽量下推以达到提前过滤数据、减少网络传输、并行计算等目的。

因此,DRDS SQL 语句优化的基本原则为:尽量让更多的计算可下推到 RDS/MySQL 上执行。

可下推计算主要包括:

  • JOIN 连接
  • 过滤条件,如 WHERE 或 HAVING 中的条件
  • 聚合计算,如 COUNT,GROUP BY 等
  • 排序,如 ORDER BY
  • 去重,如 DISTINCT
  • 函数计算,如 NOW() 函数等
  • 子查询

通过 explain optimizer + sql 可以看到查询改写的具体过程

Project/Filter 下推

下面给出一条SQL的执行计划生成过程的例子。Filter和Project被先后下推到LogicalView算子里面。

Filter和Project下推可以达到提前过滤数据,减少网络传输等效果。

  1. > explain optimizer select c_custkey,c_name from customer where c_custkey = 1;

x

Limit/Sort 下推

下面给出一条SQL的执行计划生成过程的例子。Sort和Limit被先后下推到LogicalView算子里面。

Sort和Limit下推可以达到提前过滤数据,减少网络传输,并行执行,减少DRDS内存占用等效果。

  1. > explain optimizer select * from customer order by c_custkey limit 10

x

Agg下推

下面给出一条SQL的执行计划生成过程的例子。Agg被下推到LogicalView算子里面。

Agg下推可以达到提前过滤数据,减少网络传输,并行执行,减少DRDS内存占用等效果。

  1. > explain optimizer select count(*) from customer group by c_nationkey;

拆分键为c_nationkey情况:

x

拆分键不为c_nationkey情况:

x

Join 下推

Join下推需要满足以下条件:

  • t1与t2表的拆分方式一致(包括分库键、分表键、拆分函数、分库分表数目)
  • Join条件中包含t1,t2表拆分键的等值关系

此外,任意表 Join广播表总是可以下推。

  1. > explain optimizer select * from t1, t2 where t1.id = t2.id;

下面给出一条sql的执行计划生成过程的例子。Join下推到LogicalView算子里面。Join下推可以达到计算离存储更近,并行执行加速的效果。

x

Join Clustering

当有多个表Join的情况,DRDS会通过Join Clustering的优化技术将Join进行重排序,将可下推的Join放到相邻的位置,从而让它可以被下推下去。下面是一个例子:

假设原join顺序为t2,t1,l2, 经过重排序之后,t2 join l2依然能下推到了LogicalView

  1. > explain select t2.id from t2 join t1 on t2.id = t1.id join l2 on t1.id = l2.id;
  2. Project(id="id")
  3. HashJoin(condition="id = id AND id = id0", type="inner")
  4. Gather(concurrent=true)
  5. LogicalView(tables="t2_[0-3],l2_[0-3]", shardCount=4, sql="SELECT `t2`.`id`, `l2`.`id` AS `id0` FROM `t2` AS `t2` INNER JOIN `l2` AS `l2` ON (`t2`.`id` = `l2`.`id`) WHERE (`t2`.`id` = `l2`.`id`)")
  6. Gather(concurrent=true)
  7. LogicalView(tables="t1", shardCount=2, sql="SELECT `id` FROM `t1` AS `t1`")

子查询下推

下面给出一条sql的执行计划生成过程的例子。子查询下推到LogicalView算子里面。

子查询下推可以达到计算离存储更近,并行执行加速的效果。

  • 子查询会先被转换成Semi/Anti Join
  • 之后如果满足上节中Join下推的判断条件,就会将Semi/Anti Join下推至LogicalView
  • 下推后的Semi/Anti Join会被还原为子查询
  1. explain optimizer select * from t1 where id in (select id from t2);

x