閱讀702 返回首頁    go 阿裏雲 go 技術社區[雲棲]


PostgreSQL的遠程數據操作---postgres_fdw

PostgreSQL提供了外部數據包裝器postgres_fdw,作用跟dblink相同,即查詢遠程數據庫中的數據信息,但是 postgres_fdw比dblink在某些場景更穩定、更方便。同時PostgreSQL也提供對其他數據庫如Oracle和MySQL等數據庫的外 部數據包裝器:oracle_fdw和mysql_fdw,可查詢Oracle和MySQL數據庫中的相關表信息。

  注意,不論使用PG的哪種外部數據包裝器,盡可能的保證兩端的表中字段的數量、類型和順序一致,否則可能導致很多問題。

下麵我們來體驗一下該功能:

測試環境準備:

在遠程數據庫上創建新的數據庫musician,並在庫裏創建表man,插入測試數據:
postgres=#
CREATE DATABASE
music=#
您現在已經連線到數據庫 "musician",用戶 "eric".
musician=>
CREATE TABLE
musician=>
INSERT 0 8000
musician=>
 count 
-------
  8000
(1 行記錄)

musician=>
             關聯列表
 架構模式 | 名稱 |  型別  | 擁有者 
----------+------+--------+--------
 public   | man  | 資料表 | eric
(1 行記錄)


在本地測試庫安裝插件postgres_fdw:
postgres=#
CREATE EXTENSION
music=>
You are now connected to database "music" as user "postgres".

創建外部服務器對象,需要指定相關信息:
對象名稱:musician_fdw_server
包裝器類型:postgres_fdw,如果要連接Oracle或者MySQL數據庫的話,可用oracle_fdw或mysql_fdw
主機IP:192.168.1.129
數據庫名稱:musician(剛剛創建的數據庫名)
端口號:5432
music=#
CREATE SERVER

創建用戶映射,相關信息:
本地用戶:eric
外部服務器對象:musician_fdw_server
遠程數據庫用戶名密碼:eric,gao
music=#  
CREATE USER MAPPING

配置外部表,相關信息:
外部表在本庫的名稱:manid
外部服務器:musician_fdw_server
外部表名:man
music=>
You are now connected to database "music" as user "postgres".
music=#
CREATE FOREIGN TABLE

注意:
  在遠程數據庫的pg_hba.conf中修改一下相關的配置:

最終這樣修改的:
# IPv4 local connections:
host    all           all            192.168.1.0/24              md5

因為遠程連接的話,PG要求是需要有密碼驗證的,設置成trust的話會報錯。

設置完成之後驗證一下查詢效果:
music=>
You are now connected to database "music" as user "postgres".
music=#
 count 
-------
  8000
(1 row)

驗證一下刪除和插入操作:
從本地刪除遠程數據庫musician中表man的所有數據:
music=>
You are now connected to database "music" as user "postgres".
music=#
DELETE 10000

在遠程數據庫執行查詢數據條目:
musician=>
 count 
-------
     0
(1 行記錄)
數據已全部清除。

從本地向遠程數據庫musician中的表man插入1萬條數據:
music=#

INSERT 0 10000

在遠程數據庫中看到1萬條數據已入賬:
musician=>
 count 
-------
 10000
(1 行記錄)


在遠程數據庫本地執行語句:
musician=>
                                                 QUERY PLAN                                                 
------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=136.00..136.01 rows=1 width=0) (actual time=26.128..26.129 rows=1 loops=1)
   ->  Seq Scan on man  (cost=0.00..116.00 rows=8000 width=0) (actual time=0.014..13.068 rows=8000 loops=1)
 Planning time: 0.045 ms
 Execution time:
(4 行記錄)

在本地數據庫本地執行語句:
music=>
                                                     QUERY PLAN                                                     
--------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=220.92..220.93 rows=1 width=0) (actual time=42.804..42.804 rows=1 loops=1)
   ->  Foreign Scan on manid  (cost=100.00..212.39 rows=3413 width=0) (actual time=2.264..41.813 rows=8000 loops=1)
 Planning time: 0.067 ms
 Execution time:
(4 rows)

看起來差別不是太大,但是測試的數據量和類型也不複雜,那我們接下來換一條語句:

遠程數據庫本地執行語句:
musician=>
                                              QUERY PLAN                                              
------------------------------------------------------------------------------------------------------
 Seq Scan on man  (cost=0.00..116.00 rows=8000 width=8) (actual time=0.012..10.277 rows=8000 loops=1)
 Planning time: 0.036 ms
 Execution time:
(3 行記錄)

本地數據庫本地執行語句:
music=>
                                                  QUERY PLAN                                                   
---------------------------------------------------------------------------------------------------------------
 Foreign Scan on manid  (cost=100.00..186.80 rows=2560 width=8) (actual time=14.445..60.194 rows=8000 loops=1)
 Planning time: 12.400 ms
 Execution time:
(3 rows)

看起來差別還是比較明顯的,更別提用到量大且複雜的生產環境中了。如果是該查詢用的不頻繁並且查詢的量不大不複雜,客戶也可以忍受響應速度,那這樣就OK。


物化視圖可以理解為是對目標表格的一個副本,可能是一模一樣的,也可能是經過篩選的。本次咱們為了改善性能,簡單的創建一個跟遠程數據庫表格一模一樣的物化視圖:

在本地數據庫創建物化視圖:
物化視圖名稱為:mv_manid,通過該視圖保存manid表能查到的數據的實體:
music=>
SELECT 8000   ---數據條目跟剛才一樣為8千條

查看一下物化視圖的性能如何:

music=>
                                                QUERY PLAN                                                
----------------------------------------------------------------------------------------------------------
 Seq Scan on mv_manid  (cost=0.00..113.04 rows=7704 width=8) (actual time=0.024..1.823 rows=8000 loops=1)
 Planning time: 0.254 ms
 Execution time:
(3 rows)

music=>
                                                   QUERY PLAN                                                   
----------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=132.30..132.31 rows=1 width=0) (actual time=1.336..1.336 rows=1 loops=1)
   ->  Seq Scan on mv_manid  (cost=0.00..113.04 rows=7704 width=0) (actual time=0.010..0.738 rows=8000 loops=1)
 Planning time: 0.032 ms
 Execution time:
(4 rows)

比manid的強不少吧?~~~

物化視圖需要對表進行刷新才能同步遠程表的數據:

在遠程數據庫表裏插入新數據:
musician=>
INSERT 0 2000
musician=>
 count 
-------
 10000
(1 行記錄)

本地庫查詢發現還是8千條數據:
music=>
 count 
-------
  8000
(1 row)

刷新一下本地的物化視圖即可看到新進來的數據:
music=>
REFRESH MATERIALIZED VIEW
music=>
 count 
-------
 10000
(1 row)

最後更新:2017-04-01 13:44:33

  上一篇:go ALICloudDB for PostgreSQL 試用報告 - 4 水平分庫 之 節點擴展
  下一篇:go ALICloudDB for PostgreSQL 試用報告 - 5 長短連接測試