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:の処理が実行される)