当前位置: 首页 > news >正文

openGauss之 无用join消除

一. 前言

    openGauss join消除是指部分场景下的left join是无实际意义的,直接去除后和去除前的sql是等价的。如下所示,select t1.* from test1 t1 left join test2 t2 on t1.c1 = t2.c1 可以等价成select t1.* from test1 t1 。

     openGauss中,Join消除的入口在remove_useless_joins函数中,本文主要介绍在openGauss中是怎样实现无用join消除的。

二. 表join的无用join消除

    join条件在满足如下条件后可以被消除,消除前后等价:

   1. join为left join,

   2. 内表的join中的on列组合满足唯一性约束,

   3. 内表是单个表

   4. 内表的列除了在on条件中外,无其他的场景使用到。

  表join表的join消除代码如下所示:

remove_useless_joinsfor (lc = list_head(root->join_info_list); lc != NULL; lc = pnext) {  // 对于所有的joinjoin_is_removable    // 判断join能不能被消除if ((sjinfo->jointype != JOIN_LEFT && sjinfo->jointype != JOIN_LEFT_ANTI_FULL) || sjinfo->delay_upper_joins ||bms_membership(sjinfo->min_righthand) != BMS_SINGLETON)return false;   // 必须要是left join和单表if (!rel_supports_distinctness(root, innerrel))return false;   // 内表join列必须是唯一性,通过判断是否有唯一索引判断joinrelids = bms_union(sjinfo->min_lefthand, sjinfo->min_righthand); // join中所有引用到的列for (attroff = innerrel->max_attr - innerrel->min_attr; attroff >= 0; attroff--) {if (!bms_is_subset(innerrel->attr_needed[attroff], joinrelids))  // attr_needed为内表引用到的列,不属于joinrelids的话就是被join以外的地方使用到,比如output target, 那不可优化return false;}foreach (l, innerrel->joininfo) {if (!clause_sides_match_join(restrictinfo, sjinfo->min_lefthand, innerrel->relids))continue; /* 必须是外表 join 内表的形式 */}if (rel_is_distinct_for(root, innerrel, clause_list)) // 再次确认内表的join列具有唯一性relation_has_unique_index_for  // 判断唯一性的列是否都在join的on条件中for (c = 0; c < ind->nkeycolumns; c++) {foreach (lc, restrictlist) {match_index_to_operand}}return true;// 需要移除的内表 innerrelid = bms_singleton_member(sjinfo->min_righthand);remove_rel_from_query   // 从simple_rel_array_size中移除innerrelidremove_rel_from_joinlist  // 从 joinlist中删除内表}

三.  子查询join的无用消除

       subquery 和 table的区别的唯一区别在于判断on的条件是否能满足唯一性约束。如下场景中子查询都可以满足唯一性约束。

    1.  join的on条件的列都在distinct中。

    2. join的on条件的列都在group by中。

    3. 带聚合函数

    4. union 不带all的场景

代码流程如下所示:

query_is_distinct_forif (query->distinctClause != NIL) {check_column_uniqueness   // distinct的所有列都在join的on条件中,满足唯一性约束,可以被消除foreach (l, groupClause) {distinct_col_search   // 能从join的on 条件中找到唯一索引列}}if (query->groupClause != NIL) {check_column_uniqueness(query->groupClause)   // group by的所有列都在on条件中也能满足唯一性约束} else {if (query->hasAggs || query->havingQual)return true;  // 带聚合函数也能满足唯一性约束}if (query->setOperations != NULL) {if (!topop->all) {     // union 不包含allforeach (l, query->targetList) {distinct_col_search   //  union的所有targer都在join的on条件中}}}

http://www.dtcms.com/a/348535.html

相关文章:

  • 如何在 IDEA 中在启动 Spring Boot 项目时加参数
  • Ubuntu 服务器无法 ping 通网站域名的问题解决备忘 ——通常与网络配置有关(DNS解析)
  • 国内使用SSH稳定使用github
  • ROS 与 Ubuntu 版本对应关系
  • 基于Transformer的知识图谱推理模型(KnowFormer)
  • 使用python进行接口测试
  • .net9 解析 jwt 详解
  • Indy HTTP Server 使用 OpenSSL 3.0
  • 采摘机器人设计cad+三维图+设计说明书
  • 学习记录(二十一)-Overleaf中图片文字间隔太大怎么办
  • 【QT入门到晋级】进程间通信(IPC)-共享内存
  • Java数据结构——7.二叉树(总览)
  • 机器学习周报十
  • 从文本树到结构化路径:解析有限元项目架构的自动化之道
  • Rust Web开发指南 第二章(Axum 路由与参数处理)
  • gcc报错解决办法
  • Maxwell学习笔记
  • 如何让FastAPI在百万级任务处理中依然游刃有余?
  • Node【文件+模块化+对象】详讲:
  • OSG库子动态库和插件等文件介绍
  • k8s原理及操作
  • LLM 中评价指标与训练概要介绍
  • AI Prompt 的原理与实战
  • 【LeetCode】分享|如何科学的刷题?
  • 【深度学习】骨干网络(Backbone)
  • 毛选一卷解析
  • VAREdit:深度解读
  • k8s部署,pod管理,控制器,微服务,集群储存,集群网络及调度,集群认证
  • 在Excel和WPS表格中打印时加上行号和列标
  • rosdep无法获取noetic源?