下推是查詢改寫的一項重要優化,利用PolarDB-X 1.0的拆分信息來優化執行計劃,使得算子盡量下推以達到提前過濾數據、減少網絡傳輸、并行計算等目的。

背景信息

根據PolarDB-X 1.0的SQL語句優化的基本原則,可以下推盡量更多的計算到存儲層MySQL上執行。

可下推計算主要包括:

  • JOIN連接
  • 過濾條件(如WHEREHAVING中的條件)
  • 計算(如COUNTGROUP BY
  • 排序(如ORDER BY
  • 去重(如DISTINCT
  • 函數計算(如NOW()函數)
  • 子查詢
說明 通過explain optimizer + sql可以看到查詢改寫的具體過程。

Project和Filter下推

一條SQL的執行計劃在如下生成過程中,Filter和Project被先后下推到LogicalView算子里面。

Filter和Project下推可以達到提前過濾數據,減少網絡傳輸等效果。

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

c_custkeycustomer的拆分鍵。c_namecustomer的名字。

Project和Filter下推

Limit和Sort下推

一條SQL的執行計劃在如下生成過程中,Sort和Limit被先后下推到LogicalView算子里面。Sort和Limit下推可以達到提前過濾數據,減少網絡傳輸、并行執行、減少PolarDB-X 1.0內存占用等效果。

> explain optimizer select * from customer order by c_custkey limit 10
Limit和Sort下推

Agg下推

一條SQL的執行計劃在如下生成過程中,Agg被下推到LogicalView算子里面。

Agg下推可以達到提前過濾數據,減少網絡傳輸,并行執行,減少PolarDB-X 1.0內存占用等效果。

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

拆分鍵為c_nationkey情況:

Agg下推_拆分鍵為c_nationkey

拆分鍵不為c_nationkey情況:

Agg下推_拆分鍵不為c_nationkey

JOIN下推

JOIN下推需要滿足以下條件:

  • t1與t2表的拆分方式一致(包括分庫鍵、分表鍵、拆分函數、分庫分表數目)。
  • JOIN條件中包含t1,t2表拆分鍵的等值關系。

此外,任意表JOIN廣播表總是可以下推。

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

一條SQL的執行計劃在如下生成過程中,JOIN下推到LogicalView算子里面。JOIN下推可以達到計算離存儲更近,并行執行加速的效果。

JOIN下推

JoinClustering

當有多個表執行JOIN操作時,PolarDB-X 1.0會通過join clustering的優化技術將JOIN進行重排序,將可下推的JOIN放到相鄰的位置,從而讓它可以被正常下推。示例如下:

假設原JOIN順序為t2、t1、l2, 經過重排序之后,t2和l2的JOIN操作依然能下推到LogicalView

> explain select t2.id from t2 join t1 on t2.id = t1.id join l2 on t1.id = l2.id;

Project(id="id")
  HashJoin(condition="id = id AND id = id0", type="inner")
    Gather(concurrent=true)
      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`)")
    Gather(concurrent=true)
      LogicalView(tables="t1", shardCount=2, sql="SELECT `id` FROM `t1` AS `t1`")

子查詢下推

一條SQL的執行計劃在如下生成過程中,子查詢下推到LogicalView算子里面。

子查詢下推可以達到計算離存儲更近,并行執行加速的效果。

  • 子查詢會先被轉換成Semi JoinAnti Join
  • 之后如果滿足上節中JOIN下推的判斷條件,就會將Semi JoinAnti Join下推至LogicalView
  • 下推后的Semi JoinAnti Join會被還原為子查詢。
explain optimizer select * from t1 where id in (select id from t2);
子查詢下推