• 4.FDW


    (这里没有提到创建外表的作用,所以既然什么查询都是要发送到远程去执行的,为什么一定要创建外表呢?可能是为了进行语法分析?)

    citus也是一种fdw。只有postgres_fdw是PostgreSQL开发组自己维护的,并且一直在优化更新。

    fdw执行sql语句的流程如下:

    1. 分析器生成一棵查询树(这里解析器与重写器都没提到,解析器可能会干活,因为语义分析是建立在词法、语法解析的基础上的。根据后面fdw不能根据归并连接中一张表的where条件推测出另一张表也需满足该条件,我怀疑重写器不会工作)
    2. 计划器或执行器连接远程数据库(以得到目标列是否有索引啊之类的信息),不同数据库的fdw使用不同的驱动连接不同的远程数据库。
    3. 如果启动了use_remote_estimate参数,则计划器执行explain命令,向远程服务器发送explain命令,虽然只有pg的远程数据库能返回可用的代价,其他如mysql数据库只能返回预估的行,这点信息显然不够我们估计代价的。如果没有启动那个参数,则使用本地的预设的常数值作为代价。
    4. 计划器生成计划树,并根据计划树生成远程数据库可识别的sql语句(逆解析)。
    5. 执行器向远程数据库发送sql语句,并接收结果,fdw负责将相应的结果转换为pg数据库可识别的格式。向Mysql远程服务器发送多条语句时,不使用事务。向pg远程数据库发送时使用事务,且事务的隔离级别为可重复读,或者可序列化(如果本地数据库也为可序列化的话)。pg使用游标来处理结果集,最后需要关闭游标,从游标中读取数据默认以100行为单位。

    fdw可以实现对外部表的增删改查、对多表的连接、排序、执行聚合函数等。但不会检测死锁。

    9.6版本以前,连接、排序、聚合函数都是将数据拉到本地执行的,这样会造成很大的网络传输数据量(查看远程数据库接收语句的log就可以发现,只有拉取数据的命令,没有操作的命令),特别对于求平均等聚合函数,以及对其中一张表有筛选条件的归并连接(如a.id<10 and a.id=b.id,那么在初始扫描b表时,也只需要取b.id<10的表出来连接,但是fdw并不能推测出这种含义,所以会将b表的所有记录全取出来。归并连接比其他连接受此影响更大,因为归并连接它还需要对b进行排序)。

    9.6以及10以后的版本,排序、聚合函数会下移,如果连接涉及的多张表在一个远程数据库中,则连接也会下移。连接下移的前提是开了xx参数,否则pg会将在远程连接的成本设为很大,从而在本地连接。

  • 相关阅读:
    Fabric.js 图形标注
    海外仓物流有哪些优缺点
    Android设计模式--Builder建造者模式
    【Go ~ 0到1 】 第六天 文件的读写与创建
    破解WIFI密码之密码字典
    【Leetcode】1573. Number of Ways to Split a String
    Python_WebSocket服务器和Python_JavaScript客户端
    (30)Verilog实现倍频【方法一】
    维也纳酒店抚州市政中心店以品牌之力创造非凡价值
    精准定位——MySQL日志学习的一天【错误、二进制、查询、慢查询】
  • 原文地址:https://blog.csdn.net/Michaelia_hu/article/details/127804172