oracle_fdw test case

前面一篇BLOG主要介绍了oracle_fdw的部署,这里来看看它的一些应用特性。
1. 摄取速度
测试从oracle数据库获取数据的速度 . 
oracle表 :
tbl_oracle_fdw(id int primary key,firstname varchar2(32),lastname varchar2(32),crt_time date);

数据量 2000W,不含索引的大小是994 MB。
insert into tbl_oracle_fdw select rownum,'zhou'||rownum,'digoal'||rownum,sysdate from dual connect by level<=20000000;
postgreSQL表 : 
tbl_copy_from_oracle (id int primary key,firstname varchar(32),lastname varchar(32),crt_time timestamp(0) without time zone);

开始获取数据 : 
digoal=> insert into tbl_copy_from_oracle (id,firstname,lastname,crt_time) select id,firstname,lastname,crt_time from tbl_oracle_fdw;

从oracle服务器的sar -n DEV输出看到的网络流量txbyt/s约1916557,994MB数据需要约531秒传输完成。
测试环境是内网,服务器网卡都是1GB的,所以网络带宽不存在问题。速度慢在ORACLE的获取接口上。如果另外再开一个同样的SQL,sar -n DEV监测到的流量将翻倍。
下面来看看真实的时间开销 :
INSERT 0 20000000
Time: 435654.745 ms

除去ORACLE的头部信息和FREEFCT的剩余空间,这个速度是可以预料的。
获取速度和oracle到oracle之间的dblink还是有很大差距的。

2. 连接复用
这一项要测试的是,当连接空闲的时候是否会复用,结果是不会。请看如下测试:
postgresql SESSION A : 
# 假设tbl_oracle_fdw是foreign表,执行下面的SQL将会开启一个到oracle的连接。
select * from tbl_oracle_fdw where id=1;

# 查看postgresql的PID
digoal=> select procpid from pg_stat_activity ;
 procpid 
---------
   25412
(1 row)

# 查看oracle下对应的session信息
SQL> select username,module,action from v$session where username='DIGOAL';

USERNAME                       MODULE                                           ACTION
------------------------------ ------------------------------------------------ --------------------------------
DIGOAL                         postgres                                         25412

# postgresql SESSION B : 
# 在确保SESSION A没有操作FOREIGN表的情况下,新开一个session
postgres@db5-> psql -h 127.0.0.1 digoal digoal
psql (9.1.0)
Type "help" for help.
digoal=> select * from tbl_oracle_fdw where id=1; 
 id | firstname | lastname |      crt_time       
----+-----------+----------+---------------------
  1 | zhou1     | digoal1  | 2011-09-15 14:11:19
(1 row)


# 查看oracle下对应的session信息
# 显然没有复用刚才的连接,新开了一个SESSION.
SQL> select username,module,action from v$session where username='DIGOAL';
USERNAME                       MODULE                                           ACTION
------------------------------ ------------------------------------------------ --------------------------------
DIGOAL                         postgres                                         27362
DIGOAL                         postgres                                         25412


3. postgreSQL session退出后连接oracle的SESSION是否断开
退出上一步测试的SESSION A,然后查看ORACLE的v$session如下,答案是postgreSQL到oracle的连接在postgresql本地的SESSION断开后随之断开。
SQL> select username,module,action from v$session where username='DIGOAL';

USERNAME                       MODULE                                           ACTION
------------------------------ ------------------------------------------------ --------------------------------
DIGOAL                         postgres                                         27362

# 还可以通过oracle_close_connections()函数来关闭当前SESSION产生的到ORACLE的连接,不能关闭其他SESSION打开的到ORACLE的连接。
# select oracle_close_connections(); 这个普通用户也可以执行。

4. 执行计划
digoal=> explain verbose select id from tbl_oracle_fdw limit 1; 
                                                QUERY PLAN                                                
----------------------------------------------------------------------------------------------------------
 Limit  (cost=3360000.00..3360000.00 rows=1 width=252100251)
   Output: id
   ->  Foreign Scan on public.tbl_oracle_fdw  (cost=3360000.00..3360000.00 rows=19392327 width=252100251)
         Output: id
         Oracle query: SELECT /*7b8c87cefce2813f580b573fb8160ca0*/ "ID" FROM digoal.tbl_oracle_fdw
         Oracle plan: SELECT STATEMENT
         Oracle plan:   TABLE ACCESS FULL TBL_ORACLE_FDW
(7 rows)

digoal=> explain verbose select id from tbl_oracle_fdw order by id limit 1;
                                                   QUERY PLAN                                                   
----------------------------------------------------------------------------------------------------------------
 Limit  (cost=19395313283402.54..19395313283402.54 rows=1 width=252100251)
   Output: id
   ->  Sort  (cost=19395313283402.54..19395313331883.35 rows=19392327 width=252100251)
         Output: id
         Sort Key: tbl_oracle_fdw.id
         ->  Foreign Scan on public.tbl_oracle_fdw  (cost=3360000.00..3360000.00 rows=19392327 width=252100251)
               Output: id
               Oracle query: SELECT /*7b8c87cefce2813f580b573fb8160ca0*/ "ID" FROM digoal.tbl_oracle_fdw
               Oracle plan: SELECT STATEMENT
               Oracle plan:   TABLE ACCESS FULL TBL_ORACLE_FDW
(10 rows)

digoal=> explain verbose select id from tbl_oracle_fdw where id=2; 
                                                  QUERY PLAN                                                  
--------------------------------------------------------------------------------------------------------------
 Foreign Scan on public.tbl_oracle_fdw  (cost=10000.00..10000.00 rows=1 width=13)
   Output: id
   Filter: (tbl_oracle_fdw.id = 2)
   Oracle query: SELECT /*21430ee36f6e64ef458e259660612a93*/ "ID" FROM digoal.tbl_oracle_fdw WHERE ("ID" = 2)
   Oracle plan: SELECT STATEMENT
   Oracle plan:   INDEX RANGE SCAN IDX_ID_1 (condition "ID"=2)
(6 rows)


接下来看看这三条语句真正的执行时间 : 
digoal=> select id from tbl_oracle_fdw order by id limit 1;
 id 
----
  1
(1 row)
Time: 99100.774 ms
digoal=> select id from tbl_oracle_fdw limit 1;
 id 
----
  1
(1 row)
Time: 15.459 ms
digoal=> select id from tbl_oracle_fdw where id=1;
 id 
----
  1
(1 row)
Time: 14.921 ms

# 相差非常之大,
首先,select id from tbl_oracle_fdw where id=1; 这句SQL快是无可非议的,因为走索引了,GET过来只有1条。
然后是 select id from tbl_oracle_fdw limit 1; 虽然是全表扫描,但是这里返回一条结果之后就不会在GET了。所以也是很快的。
最慢的是select id from tbl_oracle_fdw order by id limit 1;原因是需要把ID全部GET到POSTGRESQL,然后排序,在LIMIT 1。这个如果能改进一下就完美了,应该在ORACLE里面排好序再过来的。

5. HINT
digoal=> explain verbose select /*+ parallel(t1,7) */ count(distinct id) from tbl_oracle_fdw t1;
                                                 QUERY PLAN                                                  
-------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=3408480.82..3408480.83 rows=1 width=252100251)
   Output: count(DISTINCT id)
   ->  Foreign Scan on public.tbl_oracle_fdw t1  (cost=3360000.00..3360000.00 rows=19392327 width=252100251)
         Output: id, firstname, lastname, crt_time
         Oracle query: SELECT /*7b8c87cefce2813f580b573fb8160ca0*/ "ID" FROM digoal.tbl_oracle_fdw
         Oracle plan: SELECT STATEMENT
         Oracle plan:   TABLE ACCESS FULL TBL_ORACLE_FDW
(7 rows)

# 显然未使用oracle的HINT
# 下面是直接在ORACLE里面使用HINT的EXPLAIN
SQL> explain plan for select /*+ parallel(t1,7) */ count(distinct id) from tbl_oracle_fdw t1;
Explained.
SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1669356901

-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name           | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT          |                |     1 |    13 |  4428   (1)| 00:00:54 |        |      |            |
|   1 |  SORT GROUP BY            |                |     1 |    13 |            |          |        |      |            |
|   2 |   PX COORDINATOR          |                |       |       |            |          |        |      |            |
|   3 |    PX SEND QC (RANDOM)    | :TQ10001       |     1 |    13 |            |          |  Q1,01 | P->S | QC (RAND)  |
|   4 |     SORT GROUP BY         |                |     1 |    13 |            |          |  Q1,01 | PCWP |            |
|   5 |      PX RECEIVE           |                |     1 |    13 |            |          |  Q1,01 | PCWP |            |
|   6 |       PX SEND HASH        | :TQ10000       |     1 |    13 |            |          |  Q1,00 | P->P | HASH       |
|   7 |        SORT GROUP BY      |                |     1 |    13 |            |          |  Q1,00 | PCWP |            |
|   8 |         PX BLOCK ITERATOR |                |    19M|   240M|  4428   (1)| 00:00:54 |  Q1,00 | PCWC |            |
|   9 |          TABLE ACCESS FULL| TBL_ORACLE_FDW |    19M|   240M|  4428   (1)| 00:00:54 |  Q1,00 | PCWP |            |
-------------------------------------------------------------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement
20 rows selected.

6. join
可以远程表和本地表join,还可以不同数据库的远程表JOIN。
如:
 table1 来自172.16.3.2上的ORACLE
 table2 来自172.16.3.3上的ORACLE
 table3 是本地表
这三个表可以任意JOIN。

【注意】
大表的全表GET一定要小心,速度是比较慢的。

【参考】

【其他fdw】
oracle_fdw test case - 德哥@Digoal - The Heart,The World.
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值