首页 > 其他分享 >查询优化-EXIST类型子连接提升

查询优化-EXIST类型子连接提升

时间:2024-03-18 14:33:34浏览次数:25  
标签:subselect sno 查询 var rtable EXIST whereClause Var 连接

瀚高数据库
目录
文档用途
详细信息

文档用途
了解exist类型的子连接提升过程

详细信息
SQL:

SELECT sno FROM STUDENT WHERE EXISTS (SELECT sno FROM score WHERE sno > STUDENT.sno);

一、执行计划:

test=# explain SELECT sno FROM STUDENT WHERE EXISTS (SELECT sno FROM score WHERE sno > STUDENT.sno);

                             QUERY PLAN

---------------------------------------------------------------------

 Nested Loop Semi Join  (cost=0.00..22497.30 rows=367 width=4)

   Join Filter: (score.sno > student.sno)

   ->  Seq Scan on student  (cost=0.00..21.00 rows=1100 width=4)

   ->  Materialize  (cost=0.00..40.60 rows=2040 width=4)

         ->  Seq Scan on score  (cost=0.00..30.40 rows=2040 width=4)

(5 rows)

查询树:

正在上传...sample21.node.jpg

优化后的查询树:

sample20.node.jpg

优化前和优化后查询树对比结合该sql的执行计划,EXIST类型的子连接提升主要操作包括:

1.SUBLINK->subselect->rtable提升到上层,和上层表构成Semi Join关系。

2.优化后的JoinExpr中的quals是Sublink->subselect->FromExpr->quals提升上来的。

3.将子连接的范围表和约束条件提升之后,需要调整subselect查询树中的Var变量中的varno和varlevelsup。

根据优化后的查询树对应的SQL是:

SELECT sno FROM student SEMI JOIN score WHERE score .sno > student .sno;

二、提升流程

  1. quals单独保存到whereClause作为约束条件
whereClause = subselect->jointree->quals;

subselect->jointree->quals = NULL;
  1. 对subselect和whereClause分别处理,目前它们中的 Var 变量的 varno 是根据 SubLink->subselect->rtable 确定的,如果这些 Var 被提升到上层,它们的 varno 就要做调整,由于要将子连接中的范围表追加到上层父查询的范围表的链表中 (rtable链表),因此子连接中的范围表的 rtindex 需要增加上层父查询的范围表链表的长度,同时对 SubLink-> subselect 中的 RangeTableRef rtindex 要按照新的 rtindex 做调整。这个在上述查询树中可以直观体现。
rtoffset = list_length(parse->rtable);

OffsetVarNodes((Node *) subselect, rtoffset, 0);

OffsetVarNodes(whereClause, rtoffset, 0);



if (IsA(node, Var))

{

  Var    *var = (Var *) node;



if (var->varlevelsup == context->sublevels_up)

{

  var->varno += context->offset;

  var->varnullingrels = offset_relid_set(var->varnullingrels,

   context->offset);

  if (var->varnosyn > 0)

   var->varnosyn += context->offset;

}

return false;

}
  1. 对 Sublink->subselect和whereClause 分别处理,如果引用了上层表的列属性,那么这个 Var的varlevelup 的值表示它是上一层的某个表的列属性,如果子连接被提升, 这个Var的varlevelsup 应该做出调整,调成为原来的值-1
IncrementVarSublevelsUp((Node *) subselect, -1, 1);

IncrementVarSublevelsUp(whereClause, -1, 1);

if (IsA(node, Var))

{

Var    *var = (Var *) node;



if (var->varlevelsup >= context->min_sublevels_up)

var->varlevelsup += context->delta_sublevels_up;

return false; /* done here */

}

image.png

image.png

  1. 将子连接的rtable附加到父查询的rtable
CombineRangeTables(&parse->rtable, &parse->rteperminfos,

			subselect->rtable, subselect->rteperminfos);
  1. 创建新的JoinTree,用subselect中的JoinTree的fromlist作为右参数,whereClause作为新的Join关系的quals
result = makeNode(JoinExpr);

result->jointype = under_not ? JOIN_ANTI : JOIN_SEMI;

result->isNatural = false;

result->larg = NULL; /* caller must fill this in */

/* flatten out the FromExpr node if it's useless */

if (list_length(subselect->jointree->fromlist) == 1)

 result->rarg = (Node *) linitial(subselect->jointree->fromlist);

else

 result->rarg = (Node *) subselect->jointree;

result->quals = whereClause;

PG处理ANY和EXIST类型的子连接,两者最主要的不同是ANY类型的子连接提升为子查询,而EXIST类型的子连接提升为表与表直接相连的方式。

标签:subselect,sno,查询,var,rtable,EXIST,whereClause,Var,连接
From: https://blog.csdn.net/pg_hgdb/article/details/136807420

相关文章

  • NFS搭建共享-ssh免密连接
    综合架构学习笔记-4-NFS1.NFS是什么?存储,部署这个软件可以实现客户机可以访问远程服务器共享资源2.优点缺点优点:免费配置方便满足做架构方案缺点:使用明文传输不安全3.nfs使用场景1.做负载均衡会用到2.数据备份实战部分4.生产部署实战---重点存储:10.0.1.1......
  • xshell--ssh免密连接
    综合架构学习笔记-4-NFS1.NFS是什么?存储,部署这个软件可以实现客户机可以访问远程服务器共享资源2.优点缺点优点:免费配置方便满足做架构方案缺点:使用明文传输不安全3.nfs使用场景1.做负载均衡会用到2.数据备份实战部分4.生产部署实战---重点存储:10.0.1.1......
  • macos 连接windows后的,delphi IDE窗体设计器变小的问题
    macos连接windows清晰度但是这样之后,屏幕是清晰了,delphiIDE窗体设计器变得很小;原因:你可以理解为IDE里的设计时窗体标题栏,就是IDE自己画的一个假的,而IDE在画这个东西时,没加进去根据DPI放大的功能;解决方法:可以看到主窗体OK了;......
  • 关于事务处理过程中,查询事务相关表的处理方式
    关于事务处理过程中,查询事务相关表的处理方式DBServerProvider.SqlDapper与repository的区别及应用场景publicoverrideWebResponseContentAudit(object[]keys,int?auditStatus,stringauditReason){Toolstools=newTools();......
  • SQL 查询优化之 WHERE 和 LIMIT 使用索引详解
    奇怪的慢sql我们先来看2条sql第一条:第二条:表的索引及数据总情况: 索引:acct_id,create_time分别是单列索引,数据库总数据为500w。通过acct_id过滤出来的结果集在1w条左右。 查询结果:第一条要5.018s,第二条0.016s为什么会是这样的结果呢?第一,acct_id和create_time都有索引,不......
  • redis-server.exe 双击闪退还显示未连接
    Redis下运行cmd:D:\Redis-x64-3.0.504>redis-server.exeredis.windows.conf报错:[7672]13Mar21:29:36.738#CreatingServerTCPlisteningsocket*:6379:bind:Noerror执行客户端(可以在下载的地方双击redis-cli.exe,也可以执行命令):D:\Redis-x64-3.0.504>red......
  • 如何不中断连接保持linux服务器持续运行 —— screen 使用介绍
     请参考ck'sblog以获取最佳观感在linux服务器上跑模型的时候,有时会在终端会话中持续了一段时间后超时断开,或者因为意外情况断网,如果正常在命令行终端执行程序时,此时会中断程序的进行,这很恼火,这就意味着要让程序持续运行,就必须得保持主机和服务器的连接,程序跑一晚上,主机就......
  • 查询端口号占用
    1.netstat-aon|findstr"8089"查询占用端口号的PID,这里为89842.tasklist|findstr"8984"通过PID查询是什么应用占用了该端口......
  • 使用JDBC查询数据库会一次性加载所有数据吗
    前几天有个小伙伴说他有个疑问:当我们发起一个查询的时候,数据库服务器是把所有结果集都准备好,然后一次性返回给应用程序服务吗(因为他们生产有个服务因为一个报表查询搞宕机了)。这样想的原因很简单,假设那个报表查询出来有几百万数据,然后一次性倾泻给应用程序了,应用没那么大内存空......
  • MySQL修改最大连接数与打开终端
    1、打开终端1)直接在开始栏搜索"mysqlcommandlineclient",能找到自带的终端2)或者cmd里mysql-uroot-p2、终端输入密码闪退的情况解决方法实际我遇到这个问题后,重启数据库就好了3、设置最大连接数等相关操作1)显示当前连接数SHOWSTATUSLIKE'Threads_connected';......