PostgreSQL查询优化逻辑优化之其他
上一节我们介绍了PostgreSQL的子查询优化,子查询优化把一部分可以优化的子查询上拉到主查询成为join。
preprocess_expression
将表达式(目标列,where,join,having)简化表达式
static Node *
preprocess_expression(PlannerInfo *root, Node *expr, int kind)
{
/*
* If the query has any join RTEs, replace join alias variables with
* base-relation variables. We must do this before sublink processing,
* else sublinks expanded out from join aliases would not get processed.
* We can skip it in non-lateral RTE functions, VALUES lists, and
* TABLESAMPLE clauses, however, since they can't contain any Vars of the
* current query level.
*/
if (root->hasJoinRTEs &&
!(kind == EXPRKIND_RTFUNC ||
kind == EXPRKIND_VALUES ||
kind == EXPRKIND_TABLESAMPLE))
expr = flatten_join_alias_vars(root, expr);
//简化常量表达式,特别处理and和or
expr = eval_const_expressions(root, expr);
//标准化条件表达式(where和having)
if (kind == EXPRKIND_QUAL)
{
expr = (Node *) canonicalize_qual((Expr *) expr);
}
/* 求解子链接的表达式,对于不能上拉的子链接会递归调用subquery_planner */
if (root->parse->hasSubLinks)
expr = SS_process_sublinks(root, expr, (kind == EXPRKIND_QUAL));
/* 给相关子查询替换变量SubPlan */
if (root->query_level > 1)
expr = SS_replace_correlation_vars(root, expr);
/*把where和having中的and表达式转换为隐含形式*/
if (kind == EXPRKIND_QUAL)
expr = (Node *) make_ands_implicit((Expr *) expr);
return expr;
}
eval_const_expressions
canonicalize_qual
使用OR分配律简化逻辑表达式,得到顶层全是AND的表达式。例如:
((A AND B) OR (A AND C)) -> (A AND (B OR C))
reduce_outer_joins
void
reduce_outer_joins(PlannerInfo *root)
{
reduce_outer_joins_state *state;
/*
* To avoid doing strictness checks on more quals than necessary, we want
* to stop descending the jointree as soon as there are no outer joins
* below our current point. This consideration forces a two-pass process.
* The first pass gathers information about which base rels appear below
* each side of each join clause, and about whether there are outer
* join(s) below each side of each join clause. The second pass examines
* qual clauses and changes join types as it descends the tree.
*/
state = reduce_outer_joins_pass1((Node *) root->parse->jointree);
/* planner.c shouldn't have called me if no outer joins */
if (state == NULL || !state->contains_outer)
elog(ERROR, "so where are the outer joins?");
reduce_outer_joins_pass2((Node *) root->parse->jointree,
state, root, NULL, NIL, NIL);
}
static void
reduce_outer_joins_pass2(Node *jtnode,
reduce_outer_joins_state *state,
PlannerInfo *root,
Relids nonnullable_rels,
List *nonnullable_vars,
List *forced_null_vars)
{
else if (IsA(jtnode, JoinExpr))
{
switch (jointype)
{
case JOIN_INNER:
break;
case JOIN_LEFT://优化为内连接
if (bms_overlap(nonnullable_rels, right_state->relids))
jointype = JOIN_INNER;
break;
case JOIN_RIGHT://优化为内连接
if (bms_overlap(nonnullable_rels, left_state->relids))
jointype = JOIN_INNER;
break;
case JOIN_FULL:
if (bms_overlap(nonnullable_rels, left_state->relids))
{
if (bms_overlap(nonnullable_rels, right_state->relids))
jointype = JOIN_INNER;//优化为内连接
else
jointype = JOIN_LEFT;//优化为左外连接
}
else
{
if (bms_overlap(nonnullable_rels, right_state->relids))
jointype = JOIN_RIGHT;//优化为右外连接
}
break;
case JOIN_SEMI:
case JOIN_ANTI:
break;
default:
elog(ERROR, "unrecognized join type: %d",
(int) jointype);
break;
}
/*剩余的右外连接优化为左外连接*/
if (jointype == JOIN_RIGHT)
{
}
/*左外连接转换为反半连接*/
if (jointype == JOIN_LEFT)
{
}
/* 递归优化之树 */
if (left_state->contains_outer || right_state->contains_outer)
{
if (left_state->contains_outer)
{
reduce_outer_joins_pass2(j->larg, left_state, root,
pass_nonnullable_rels,
pass_nonnullable_vars,
pass_forced_null_vars);
}
if (right_state->contains_outer)
{
reduce_outer_joins_pass2(j->rarg, right_state, root,
pass_nonnullable_rels,
pass_nonnullable_vars,
pass_forced_null_vars);
}
bms_free(local_nonnullable_rels);
}
}
else
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(jtnode));
}
消除外连接,不是所有的外连接都能转换为内连接,只有基于"空值拒绝"的才可以。其实SQL还是外连接,只是这样可以通过调整多表连接顺序优化。
例如:left join,join后右边的列被非空条件排除
select * from x left join y on (x.x = y.y) where y.y is not null;
优化后只有FULL JOIN
PostgreSQL查询优化逻辑优化之其他的更多相关文章
- PostgreSQL查询优化简介
简介 PostgreSQL查询优化器执行过程 语法分析:生成查询树 语义检查:对SQL表达的语义进行检查 查询优化 视图重写 逻辑优化:子查询优化,条件化简,等价谓词重写,连接消除,得到逻辑计划 物理 ...
- PostgreSQL查询优化器之grouping_planner
grouping_planner主要做了3个工作: 对集合进行处理 对非SPJ函数进行优化 对SQL查询语句进行物理优化 grouping_planner实现代码如下: static void gro ...
- Scrum立会报告+燃尽图(十二月六日总第三十七次):程序功能逻辑优化
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...
- SQL 查询优化 索引优化
sql语句优化 性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化. 为了获得稳定的执行性能,SQL语句越简单越好.对复杂的 ...
- PostgreSQL之性能优化(转)
转载自:https://blog.csdn.net/huangwenyi1010/article/details/72853785 解决问题 前言 PostgreSQL的配置参数作为性能调优的一部分, ...
- 数据库查询优化-SQL优化
1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null可以在num上设置默 ...
- PostgreSQL查询优化之子查询优化
子查询优化 上拉子连接 上拉子连接主要是把ANY和EXIST子句转换为半连接 void pull_up_sublinks(PlannerInfo *root) { Node *jtnode; //子连 ...
- SQL 逻辑优化 case when 转为 union all
通常数据库的优化从硬件层面去考虑可分为4个方面: CPU:即降低计算复杂度,如减少sql各类聚合函数,窗口函数,case when等. IO :(较少查询结果集过程中对数据的访问量.数据优化很大程度从 ...
- PostgreSQL的参数优化
硬件和软件信息 CPU: Intel(R) Xeon(R) CPU E5-2683 v3 @ 2.00GHz 2 sockets / 28 cores / 56 threads内存: 256GB of ...
随机推荐
- VS2015 提示 无法启动 IIS Express Web 服务器
好久没有写东西了,不是没的写,是没时间了,今天快下班了,正好遇到这个一个问题,我就记录下来,以防忘记. 我定义了一个项目,Demo代码也写好了,然后,我们就把写好的项目代码加入到了源代码管理工具里.然 ...
- mysql开启调试日志general_log开启跟踪日志
general_log = 1 general_log_file = /tmp/umail_mysql.log 有时候,不清楚程序执行了什么sql语句,但是又要排除错误,找不到原因的情况下, 可以在m ...
- mysql常用连接查询
连接数据库PDO $user = "root"; //数据库连接账号 $pass = "root"; //数据库连接密码 $dbname = "tes ...
- [solution] JZOJ-5458 质数
[solution] JZOJ-5458 质数 题面 Description 小X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感.小X 认为,质数是一切自然数起源的地方. 在小X ...
- Avoid Inputing Password While Pushing/Pulling Git Project
If we add public key in our git account, we can pull/push project easily without password. However, ...
- Go语言正则模块
基本使用 import "bytes" import "fmt" import "regexp" func main() { //这个测试一 ...
- kaldi的TIMIT实例二
============================================================================ MonoPhone Training & ...
- 项目Alpha冲刺(团队4/10)
项目Alpha冲刺(团队4/10) 团队名称: 云打印 作业要求: 项目Alpha冲刺(团队) 作业目标: 完成项目Alpha版本 团队队员 队员学号 队员姓名 个人博客地址 备注 221600412 ...
- Javascript高级编程学习笔记(3)—— JS中的数据类型(1)
前一段时间由于事情比较多,所以笔记耽搁了一段时间,从这一篇开始我会尽快写完这个系列. 文章中有什么不足之处,还望各位大佬指出. JS中的数据类型 上一篇中我写了有关JS引入的Script标签相关的东西 ...
- localStorage 存满了怎么办?
先来几道面试题 1.a.meituan.com 和 b.meituan.com 这两个域能够共享同一个 localStorage 吗? 2.在 webview 中打开一个页面:i.meituan.co ...