背景

我们在做综合应用项目的时候,通常会面临客户的每个应用系统使用各自的数据库,或者存放在不同的服务器。查询报表可能使用多个应用数据,这样就需要跨库读取数据表或视图。

KINGBASE_FDW 是一种外部访问接口,它可以被用来访问存储在外部的数据。想要使用fdw访问数据需要先确保:网络通,数据库访问配置(sys_hba.conf)正常,同时远端数据库的用户必须有表的相关权限。

简述KINGBASE_FDW

  1. 创建扩展 kingbase_fdw

    create extension kingbase_fdw;
  2. 创建远程Server

    create server srv_test foreign data wrapper kingbase_fdw options(host '127.0.0.1',port '54321',dbname 'test');
  3. 创建User maping

    create user mapping for kingbase server srv_test options (user 'kingbase', password '123456');
  4. 创建外部表

    create foreign table public.test_tab01 (
    id integer ,
    c1 text
    ) server srv_test options (schema_name 'public', table_name 'tab01');
  5. 测试外部表

    • 读取全部数据
    explain analyze  select * from public.test_tab01;
    
    Foreign Scan on test_tab01  (cost=100.00..150.95 rows=1365 width=36) (actual time=0.230..509.699 rows=1000000 loops=1)
    Planning Time: 0.041 ms
    Execution Time: 532.775 ms
    • 支持索引
    explain analyze select * from public.test_tab01 where id = 1000 ;
    
    Foreign Scan on test_tab01  (cost=100.00..150.95 rows=1365 width=36) (actual time=0.230..0.440 rows=1 loops=1)
    Planning Time: 0.041 ms
    Execution Time: 0.485 ms

本地与外部表的关联查询

  1. 本地表与外部表的关联查询

    首先将外部表的数据缓存到本地,然后与本地表进行hash join。

    explain analyze select * from test02 a join public.tab01_db b on a.id = b.id  where a.id <= 1000;
    
    Hash Join  (cost=153.85..40186.87 rows=1081 width=37) (actual time=0.421..568.423 rows=1000 loops=1)
    Hash Cond: (b.id = a.id)
    -> Foreign Scan on tab01_db b (cost=100.00..37508.00 rows=1000000 width=25) (actual time=0.211..512.571 rows=1000000 loops=1)
    -> Hash (cost=40.34..40.34 rows=1081 width=12) (actual time=0.202..0.203 rows=1000 loops=1)
    Buckets: 2048 Batches: 1 Memory Usage: 59kB
    -> Index Scan using test02_pkey on test02 a (cost=0.42..40.34 rows=1081 width=12) (actual time=0.011..0.120 rows=1000 loops=1)
    Index Cond: (id <= 1000)
    Planning Time: 0.168 ms
    Execution Time: 568.608 ms
  2. 使用lateral改写查询

    Nested Loop 虽然没有读取外部表的全部数据,但多次通过session读取外部表,使得执行时间较长。如果loops数值更大,则执行时间远超整体读取数据方式。

    explain analyze select * from test02 a
    join lateral ( select * from public.tab01_db b where a.id = b.id limit all) b on true
    where a.id <= 1000; Nested Loop (cost=100.42..21628731.58 rows=1081 width=37) (actual time=0.224..102.295 rows=1000 loops=1)
    -> Index Scan using test02_pkey on test02 a (cost=0.42..40.34 rows=1081 width=12) (actual time=0.012..0.354 rows=1000 loops=1)
    Index Cond: (id <= 1000)
    -> Foreign Scan on tab01_db b (cost=100.00..20008.02 rows=1 width=25) (actual time=0.084..0.084 rows=1 loops=1000)
    Planning Time: 0.138 ms
    Execution Time: 102.522 ms
  3. 利用数组改写查询

    利用数组,可以一次性读取所需外部表的少量数据,即避免读取多余数据量,又防止多次建立session而产生的执行时长。由于是通过session读取外部表数据,cpu_tuple_cost默认值0.01会影响执行计划的正确性,建议设置cpu_tuple_cost值0.2 以上。

    explain analyze
    with a as (select * from test02 where id <= 1000),
    ids as ( select array(select id from a) ids),
    b as ( select b.* from tab01_db b, ids where id = any (ids))
    select /*+set(cpu_tuple_cost 0.2)*/ *
    from a, b
    where a.id = b.id; Hash Join (cost=813.27..220724.94 rows=1 width=37) (actual time=1.045..2.281 rows=1000 loops=1)
    Hash Cond: (b.id = a.id)
    CTE a
    -> Index Scan using test02_pkey on test02 (cost=0.42..40.34 rows=1081 width=12) (actual time=0.011..0.122 rows=1000 loops=1)
    Index Cond: (id <= 1000)
    InitPlan 2 (returns $1)
    -> CTE Scan on a a_1 (cost=0.00..21.62 rows=1081 width=4) (actual time=0.013..0.246 rows=1000 loops=1)
    -> Foreign Scan on tab01_db b (cost=100.00..220010.10 rows=10 width=25) (actual time=0.953..2.048 rows=1000 loops=1)
    -> Hash (cost=432.40..432.40 rows=1081 width=12) (actual time=0.086..0.086 rows=1000 loops=1)
    Buckets: 2048 Batches: 1 Memory Usage: 59kB
    -> CTE Scan on a (cost=0.00..432.40 rows=1081 width=12) (actual time=0.000..0.037 rows=1000 loops=1)
    Planning Time: 0.192 ms
    Execution Time: 2.471 ms

    总结

    外部表在查询中,属于“黑盒”,所以必须通过lateral、CTE或子查询,使得外部表可以接受过滤条件。

    综合考虑查询脚本的复杂程度,建议需要外部表数据时,极少量则使用lateral,少于30%使用数组方式,多于30%使用整体方式。

KingabseES kingbase_fdw 跨库关联查询的更多相关文章

  1. T-SQL——关于跨库连接查询

    目录 0. 同一台服务器不同数据库 1. 使用跨库查询函数--OpenDataSource() 2. 使用链接服务器(Linking Server) 3. 使用OpenDataSource()函数和链 ...

  2. oracle跨库连接查询

    一.授权(本地客户器端授权当前用户) grant create database link to szfile 第一种连接方法:配置本地数据库服务器的tnsnames.ora文件 SZFILE = ( ...

  3. 2020-07-07:mysql如何实现跨库join查询?

    福哥答案2020-07-07: 1.同服务跨库.表名称带上库名.SELECT * FROM 数据库名称1.表名称 JOIN 数据库名称2.表名称 ON 数据库名称1.表名称.tid = 数据库名称2. ...

  4. Mysql的跨服务器 关联查询--Federated引擎

    1.确认开启Federated引擎     查询FEDERATED功能是否开启: show ENGINES;       2.如果状态为NO则需修改my.ini文件,增加一行federated配置: ...

  5. springboot整合mybatis进行跨库查询

    业务场景: 当一个公司大了之后就会将各种业务进行分开,最简单的就是例如:公司的机构表,那么就会将他们分成开来,那么就会在一个实例中, 如果要获取相关信息就会去关联这张表进行关联查询 从而导致了跨库关联 ...

  6. 如何玩转跨库Join?跨数据库实例查询应用实践

    背景 随着业务复杂程度的提高.数据规模的增长,越来越多的公司选择对其在线业务数据库进行垂直或水平拆分,甚至选择不同的数据库类型以满足其业务需求.原本在同一数据库实例里就能实现的SQL查询,现在需要跨多 ...

  7. mysql 跨库查询问题

    MySQL实现跨服务器查询 https://blog.csdn.net/LYK_for_dba/article/details/78180444 mysql> create database l ...

  8. mysql跨库联表查询

    首先要了解database与instance区别,见<MySQL中的实例.数据库关系简介> 跨库分为同一个instance下的跨库和不同instance下的跨库. 一.同一个MySQL实例 ...

  9. 如何使用SQL SERVER数据库跨库查询

    SQL Server中内置了数据库跨库查询功能,下面简要介绍一下SQL Server跨库查询.首先打开数据源码:OPENDATASOURCE不使用链接的服务器名,而提供特殊的连接信息,并将其作为四部分 ...

  10. SQL Server跨库查询

    方式一: 语句 SELECT * FROM 数据库A.dbo.表A a, 数据库B.dbo.表B b WHERE a.field=b.field "DBO"可以省略 如 SELEC ...

随机推荐

  1. csplit命令

    csplit命令 csplit命令将用PATTERN分隔的FILE文件输出到文件xx00.xx01....,并将每个文件的字节数输出到标准输出. 语法 csplit [OPTION]... FILE ...

  2. el-upload使用http-request自定义上传和进度条实战

    介绍 项目中发现使用默认的el-upload上传动作发送上传请求的时候不会带上请求头,于是想通过自定义请求也就是http-request来自定义上传.实践证明这条路是通的,不过有个小问题就是原本上传的 ...

  3. maven打包时打包指定的lib文件夹

    今天在打包自己的spring boot项目时遇到了问题, 报找不到类和符号. 因为我有些依赖是放在项目lib文件夹中,那么打包的时候要连把它一起打包. 修改pom.xml, 添加一下内容: <b ...

  4. Java并发编程实例--13.方法同步(synchronized)

    使用synchronized关键字去控制对某个方法的并发调用. 某一时段内,只能有一个线程可以读取该方法. 其他线程需要等待前面线程调用完毕后方可调用. 不过,静态方法有着不同的行为. 虽然也是每次只 ...

  5. 【ACM专项练习#03】打印图形、栈的合法性、链表操作、dp实例

    运营商活动 题目描述 小明每天的话费是1元,运营商做活动,手机每充值K元就可以获赠1元,一开始小明充值M元,问最多可以用多少天? 注意赠送的话费也可以参与到奖励规则中 输入 输入包括多个测试实例.每个 ...

  6. 对于Celery原理的简单理解

    参考博客: https://www.cnblogs.com/forward-wang/p/5970806.html https://blog.csdn.net/cuomer/article/detai ...

  7. jupyterlab安装和优化

    说明 JupyterLab(官网https://jupyter.org)是一个交互式的代码编辑器,打开它会打开一个网页,可以在其中编写代码,即时执行,快速得到结果(包括代码返回值.统计图和界面交互图) ...

  8. 【Azure Developer】在微软云中国区,如何使用Microsoft GraphAPI连接到B2C Tenant

    问题描述 如题所述,当在中国区使用Microsoft GraphAPI连接B2C Tenant时候,如何来设置中国区的Endpoint呢?在GitHub的示例中,并没有示例介绍如何连接中国区.如 问题 ...

  9. 从 Neo4j 导入 Nebula Graph 实践见 SPark 数据导入原理

    本文主要讲述如何使用数据导入工具 Nebula Graph Exchange 将数据从 Neo4j 导入到 Nebula Graph Database.在讲述如何实操数据导入之前,我们先来了解下 Ne ...

  10. 面试官问我会ES么,我说不会,抓紧学起【ES(一)聚合分析篇】

    ES聚合分析 1.metric(指标)聚合 1.1 单值分析 min 求指定字段的最小值 # 求价格的最小值 { "size":0, "aggs":{ &quo ...