本文简单描述了Postgresql服务器接收到查询后到返回给客户端结果之间一般操作顺序,总的流程图如下:

第一步:

客户端程序可以是任何符合 PostgreSQL 协议规范的程序,如 JDBC 驱动。PostgreSQL 服务器使用 postmaster 主进程对特定的TCP/IP端口进行监听,当有客户端发出连接请求时,postmaster 主进程派生出一个新的叫 postgres 的服务器进程与客户端进行通信。 postgres 进程之间使用信号灯和共享内存进行通信,以确保在并行的数据访问过程中的数据完整性。一旦建立起来连接, 客户端进程就可以向服务器进程(postgres进程)发送查询了,查询是通过纯文本传输的。

第二步:  

查询发送到服务器进程之后,服务器进程(postgres进程)调用分析器检查分析查询字串的语法。检查分析阶段分为两个过程:裸分析和语意分析。

(1)裸分析

分析器首先检查查询字串的语法,如果语法正确,则创建一个分析树, 否则返回错误。Postgresql使用著名的Unix工具 lex 和 yacc来构建分析器和词法器。词法器在文件 scan.l里定义,负责识别标识符,SQL 关键字等,对于发现的每个关键字或者标识符都会生成一
个标记并且传递给分析器;分析器在文件 gram.y 里定义,包含一套语法规则和触发规则时执行的动作。 动作代码(实际上是 C 代码)用于建立分析树。
(2)语意分析

在分析器处理之后,转换处理程序接收分析器传过来的分析树, 解析语意(语意理解查询中引用了哪个表,哪个函数以及哪个操作符),生成查询树。本过程生成的查询树在很大程度上类似于裸分析阶段生成的分析树,但是在细节上有很多区别。 比如,在分析树里的 FuncCall 节点代表那些看上去像函数调用的东西。 根据引用的名字是一个普通函数还是一个聚集函数, 这个可能被转换成一个 FuncExpr 或者一个 Aggref 节点。 同样,有关字段和表达式结果的具体数据类型也添加到查询树中。

第三步:

重写系统是一个存在于分析器阶段和规划器/优化器之间的一个模块,输入和输出都是查询树。

第四步:  

规划器/优化器的任务是创建一个优化后的执行规划。 SQL 查询根据每个关系(实际上就是表)上索引的不同,可以以多种不同的方式执行。

对一个关系总是可以进行一次顺序查找, 所以总是会创建只使用顺序查找的规划。 假设一个关系上定义着一个索引(例如 B-tree 索引), 并且一条查询包含约束 relation.attribute OPR constant,如果 relation.attribute 碰巧匹配 B-tree 索引的关键字并且

OPR 又是列出在索引的操作符表中的操作符中的一个, 那么将会创建一个使用 B-tree 索引扫描该关系的规划。 如果还有别的索引, 而且查询里面的约束又和那个索引的关键字匹配,则还会生成更多的规划。有三种可能的连接策略:

嵌套循环连接:对左边的关系里面找到的每条元组都对右边关系进行一次扫描。 这个策略容易实现,但是可能会很耗费时间。 (但是,如果右边的关系可以用索引扫描,那么这个可能就是个好策略。 我们可以用来自左手边关系的当前行的数值为键字进行对右手边关系

的索引扫描。)

融合排序连接:在连接开始之前,每个关系都对连接字段进行排序。 然后对两个关系并行扫描,匹配的行就组合起来形成连接行。 这种联合更有吸引力,因为每个关系都只用扫描一次。 要求的排序步骤可以通过明确的排序步骤,或者是使用连接键字上的索引按照恰当

的顺序扫描关系。

散列连接:首先扫描右边的关系,并用连接的字段作为散列键字装载进入一个散列表, 然后扫描左边的关系,并将找到的每行用作散列键字来以定位表里匹配的行。

在寻找完所有可能的单个关系的规划后, 接着创建连接各个关系的规划。 规划器/优化器首先考虑在 WHERE 条件里存在连接子句的连接(比如 where rel1.attr1=rel2.attr2),没有连接子句的的连接只会在没有别的选择的时候才考虑,规划器/优化器为它们认为可能
的所有的连接关系对生成规划,检查不同的连接顺序可能,找出开销最小的。

不论使用何种规划,最终都会生成相同的结果集。如果可能,查询优化器将检查每个可能的执行规划,最终选择认为运行最快的执行规划。在有些情况下,特别是在正在执行的查询涉及大量连接操作的时候,检查一个查询所有可能的执行方式会花去很多时间和内存空间

,为了在合理的时间里判断一个合理的(而不是优化的)查询计划, PostgreSQL 使用“基因查询优化”。

第五步:

执行器接受规划器/优化器传过来的查询规划后进行递归处理,抽取所需要的行集合。执行器处理所有的四种基本 SQL 查询类型: SELECT,INSERT,UPDATE, 和 DELETE。对于 SELECT 而言,顶层的执行器代码发送查询规划树返回的每一行给客户端。 对于 INSERT,查询规划树返回的每一行都插入到 INSERT 声明的目标表中。 (一个简单的 INSERT ... VALUES 命令创建一个简单的规划树,包含一个 Result 节点,它只计算得出一个结果行。 但是 INSERT ... SELECT 可能需要执行器的全部能力。) 对于 UPDATE,规划器安排每个计算出来的行都包括所有更新的字段,加上原来的目标行的 TID (元组 ID,或者行 ID); 执行器的顶层使用这些信息创建一个新的更新过的行,并且标记旧行被删除。对于 DELETE, 规划实际上返回的唯一的一个字段是 TID,然后执行器的顶层简单地使用这个 TID 访问每个目标行,并且把它们标记为已删除。

postgresql查询的处理过程的更多相关文章

  1. 小觑数据库(SqlServer)查询语句执行过程

    近年来,越来越多的NoSql产品不断的以技术革命的者的身份跳出来:“你看哥是多么的快,你们关型型数据库真是战五渣阿”.是的,高性能的场景下NoSql真的很出彩.而我们关系型数据库只能在墙角哭泣&quo ...

  2. MySQL查询语句执行过程及性能优化(JOIN/ORDER BY)-图

    http://blog.csdn.net/iefreer/article/details/12622097 MySQL查询语句执行过程及性能优化-查询过程及优化方法(JOIN/ORDER BY) 标签 ...

  3. postgresql查询语句

    //查询表名称SELECT tablename FROM pg_tablesWHERE tablename NOT LIKE 'pg%'AND tablename NOT LIKE 'sql_%' O ...

  4. MySQL查询语句执行过程及性能优化-基本概念和EXPLAIN语句简介

    网站或服务的性能关键点很大程度在于数据库的设计(假设你选择了合适的语言开发框架)以及如何查询数据上. 我们知道MySQL的性能优化方法,一般有建立索引.规避复杂联合查询.设置冗余字段.建立中间表.查询 ...

  5. MySQL查询语句执行过程及性能优化-查询过程及优化方法(JOIN/ORDER BY)

    在上一篇文章MySQL查询语句执行过程及性能优化-基本概念和EXPLAIN语句简介中介绍了EXPLAIN语句,并举了一个慢查询例子:

  6. SQL嵌套子查询和相关子查询的执行过程有什么区别(推荐)

    SQLServer子查询可以分为 相关子查询 和 嵌套子查询 两类.前提, 假设Books表如下: 类编号 图书名 出版社 价格 ----------------------------------- ...

  7. [转]MySQL查询语句执行过程详解

    Mysql查询语句执行原理 数据库查询语句如何执行?语法分析:首先进行语法分析,对使用sql表示的查询进行语法分析,生成查询语法分析树.语义检查:检查sql中所涉及的对象以及是否在数据库中存在,用户是 ...

  8. Mysql查询语句执行过程

    Mysql查询语句执行过程   Mysql分为server层和存储引擎两部分,或许可以再加一层连接层   连接层(器) Mysql使用的是典型的C/S架构.连接器通过典型的TCP握手完成连接. 需要注 ...

  9. 5个容易忽视的PostgreSQL查询性能瓶颈

    PostgreSQL 查询计划器充满了惊喜,因此编写高性能查询的常识性方法有时会产生误导.在这篇博文中,我将描述借助 EXPLAIN ANALYZE 和 Postgres 元数据分析优化看似显而易见的 ...

随机推荐

  1. WCF服务承载(笔记)

    自托管(也做自承载) 承载 WCF 服务最灵活.最便捷的方法就是进行自承载.要能够自承载服务,必须满足两个条件.第一,需要 WCF 运行时:第二,需要可以承载 ServiceHost 的托管 .NET ...

  2. PHP 数据库操作类:ezSQL

    EZSQL类介绍: 下载地址:http://www.jb51.net/codes/26393.htmlezsql是一个小型的快速的数据库操作类,可以让你很容易地用PHP操作各种数据库( MySQL.o ...

  3. Unity3d uGUI适配

    Cavas: 1.Render Model设置为:Screen Space- Camera.如果想在UI前面加特效我可以在创建一个摄像机(UIForward)深度大于这个UICamera就行了. 2. ...

  4. EL函数以及自定义标签的应用

    一.EL函数(调用普通类的静态方法) 编写步骤(自定义EL函数的编写步骤即自定义标签的编写步骤): ①编写一个普通的java类,提供一个静态方法,功能自定,例如下: package cn.wzbril ...

  5. SecureCRT中python脚本编写

    SecureCRT中python脚本编写学习指南 SecureCRT python 引言 在测试网络设备中,通常使用脚本对设备端进行配置和测试以及维护:对于PE设备的测试维护人员来说使用较多是Secu ...

  6. UI--普通控件总结1--控件使用

    本文目录 0.UIView常用的属性和操作 0_1.UIView常见的属性 0_2.UIView状态 0_3.UIView常用的方法 1.文本框UITextField和文本视图UITextView 1 ...

  7. UI测试测试分析

    解析:jQuery easyUI是基于jQuery框架在使用之前应该先引入jquery框架否则jQuery easyUI 将失效故D错误 解析: JQuery UI下的menu插件的使用,menu提供 ...

  8. android studio的Beta, Canary, Dev, Stable四种Channel版本介绍、分析与选择

    一.概述 在Android Studio下载官网上,有如下介绍: ` Android Studio's built-in update mechanism can be set to receive ...

  9. 完全卸载MySQL重新安装MySQL

    在"运行(win+R)"里键入regedit进入注册表, 输入之后回车(Enter)确认. 确认之后进去注册表界面 1.HEKY_LOCAL_MACHINE\SOFTWARE\MY ...

  10. 【整理】深入理解拉格朗日乘子法(Lagrange Multiplier) 和KKT条件

    在求解最优化问题中,拉格朗日乘子法(Lagrange Multiplier)和KKT(Karush Kuhn Tucker)条件是两种最常用的方法.在有等式约束时使用拉格朗日乘子法,在有不等约束时使用 ...