Optimizer: in (subquery)の最適化

pull_up_IN_clauses(), convert_IN_to_join()で、in句のsubqueryを上位の階層のqueryにマージしている。

select a.* from accounts a
where a.bid in (select bid from branches b where b.bid < 10)

このSQLが以下のようになる。

select a.* from accounts a,
    (select distinct bid from branches b where b.bid < 10) IN_subquery
where a.bid = IN_subquery.bid

subqueryをメインのqueryへマージすることによりJoinの選択肢が多くなり、より効率の良いアクセスパスを探すことができる。

convert_IN_to_join()の前半部分で,subqueryがマージ可能かチェックしている。
主なチェック条件

  • subLinkTypeがANY_SUBLINKであること
  • operationが"="であること
  • subselectが親queryのパラメータを必要としていないこと(相関副問い合わせではないこと)

マージ可能な場合,以下の処理を行う。

  • subqueryをfromlistへ追加
  • where句に追加する条件を作成(これが戻り値になり,subqueryを置き換える)
  • root->in_info_listに情報を追加

subqueryを書き換えてdistinctを追加するのではく,root->in_info_listに情報を追加することによって、fromlistへ追加したsubqueryがinをマージしたものだと表現している。
root->in_info_listは,make_join_rel()で評価され,subqueryの検索結果をユニークにするようなパスが作成される。(make_join_rel()のswitchで,case JOIN_IN:の処理が実行される)