adsas數據庫去O記

  adsas 數據庫是用於廣告買量數據分析;在17年由 Oracle 遷移到 PostgreSQL。現把以前的遷移筆記整理下。本次遷移表91個;存儲過程21個;數據庫大小2G。 html

1. 準備PostgreSQL數據庫

  安裝PostgreSQL數據庫 參考 PostgreSQL簡單安裝手冊 ; sql

       在安裝PostgreSQL數據庫以前;首先要對數據庫硬件要作基準評測;會影響是否能取代Oracle服務器。安裝完成以後;須要建立同名 數據庫/用戶/schema。數據庫

2. 配置Ora2Pg遷移工具

  Ora2Pg是一個免費的工具,用於將Oracle數據庫遷移到PostgreSQL兼容的模式。它鏈接您的Oracle數據庫,自動掃描並提取它的結構或數據,而後生成能夠裝載到PostgreSQL數據庫的SQL腳本。Ora2Pg能夠從逆向工程Oracle數據庫到大型企業數據庫遷移,或者簡單地將一些Oracle數據複製到PostgreSQL數據庫中。它很是容易使用,而且不須要任何Oracle數據庫知識,而不須要提供鏈接到Oracle數據庫所需的參數。服務器

  安裝配置文檔架構

3. 利用Ora2Pg導出數據並導入PostgreSQL

  在上一篇成功安裝 Ora2Pg 工具;接下來咱們利用Ora2Pg導出數據。oracle

3.1 配置Oracle客戶端鏈接配置文件

[postgres@oracle166 config]$ tnsping ora165

TNS Ping Utility for Linux: Version 11.2.0.4.0 - Production on 12-OCT-2018 16:45:22

Copyright (c) 1997, 2013, Oracle.  All rights reserved.

Used parameter files:

Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = ******)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = orcl)))
OK (10 msec)

  固然該步驟也能夠省略。在接下來配置ora2pg.conf文件有講解app

3.2 配置ora2pg.conf

ORACLE_DSN  dbi:Oracle:ora165  
ORACLE_USER adsas
ORACLE_PWD  easouadsas166
LOGFILE /home/postgres/log/Ora2Pg.log
SCHEMA  adsas   
TYPE TABLE SEQUENCE COPY
PG_NUMERIC_TYPE    0
PG_INTEGER_TYPE    1
DEFAULT_NUMERIC float
SKIP    fkeys pkeys ukeys indexes checks
NLS_LANG    AMERICAN_AMERICA.UTF8
OUTPUT     adsas.sql

  只導出 TABLE,SEQUENCE。存儲過程,函數,DBLINK,視圖等須要改寫;dom

參數配置查考函數

3.3 導出數據

[postgres@oracle166 config]$ ora2pg -c ora2pg.conf

3.4 導入PostgreSQL

[postgres@oracle166 ]$ psql adsas adsas
psql (9.6.0)
Type "help" for help.

adsas=> \i /home/postgres/config/adsas.sql

  表數據跟序列已成功導入;接下來的開始改寫存儲過程和函數。工具

4. PostgreSQL建立oracle兼容函數(Orafce)

  在改寫存儲過程/函數以前;先安裝Oracle兼容函數(Orafce);它會讓你以爲PostgreSQL跟Oracle寫法沒什麼區別PostgreSQL是和Oracle最接近的企業數據庫,包括數據類型,功能,架構和語法等幾個方面。甚至大多數的平常應用的性能也不會輸給Oracle。可是Oracle有些函數或者包,默認PostgreSQL是沒有的,須要安裝orafce包來實現這些兼容性。

  安裝文檔

  如今orafce已經包含了以下內容。

1. 類型 date, varchar2 and nvarchar2
2. 函數 concat, nvl, nvl2, lnnvl, decode, bitand, nanvl, sinh, cosh, tanh and oracle.substr
3. dual 表
4. package : 
    dbms_output
    utl_file
    dbms_pipe
    dbms_alert
    PLVdate
    PLVstr and PLVchr
    PLVsubst
    DBMS_utility
    PLVlex
    DBMS_ASSERT
    PLUnit
    DBMS_random

5. 安裝PostgreSQL中調試工具plpgsql存儲過程

  這個我感受沒多大用;能夠忽略!

  安裝文檔

6. 存儲過程/函數改寫過程

  A/G

7. Oracle遷移PG代碼優化

  經存儲過程/函數改寫完成;代碼要跟Oracle等同;執行時長跟Oracle上面的時長是否差很少;發如今Oracle上面執行 12s;而改寫的代碼須要 256s;相差21倍之多。這差距不是通常的大。一樣的代碼可能在Oracle執行效果要好;這跟數據庫底層代碼有關。

7.1 insert ... on conflict 妙用

  經覈查;其中有條SQL花了將近240s的時間。

 INSERT INTO TBL_AD_CLICK_LOG  
    SELECT *
      FROM TMP_AD_CLICK_LOG
     WHERE (ES_APP_ID, IDFA_SUM) NOT IN
           (SELECT ES_APP_ID, IDFA_SUM FROM TBL_AD_CLICK_LOG);

  表TBL_AD_CLICK_LOG: 存放全部已排重的點擊數;數據量有40萬條。
  表TMP_AD_CLICK_LOG: 存放當天已排重點擊數;
該SQL目的就是避免重複的 idfa_sum 在插入表 TBL_AD_CLICK_LOG;以達到去重的效果。該SQL在Oracle上運行時長1s左右。然而在PG上運行時長將近240s。效率差。與這SQL等價且高效的SQL。

INSERT INTO TBL_AD_CLICK_LOG  
 SELECT *
FROM TMP_AD_CLICK_LOG on conflict (ES_APP_ID, IDFA_SUM) do nothing;

  使用該SQL以前需建立惟一索引;

CREATE UNIQUE INDEX IND_AD_CLICK_IDFA ON TBL_AD_CLICK_LOG(ES_APP_ID, IDFA_SUM);

  優化後;在PostgreSQL執行一次調度不到5s;相比Oracle的執行一次調度須要12s還短。

7.2 高效刪除重複數據

  在前例中;須要建立惟一索引;可是表TBL_AD_CLICK_LOG存在重複記錄;因爲與媒體對接測試的數據爲清理。刪除表中重複數據;想都不用想用rowid;在PG中;ctid跟rowid對應。因此SQL天然而然就出來了。放到PostgreSQL上執行;執行了 396s 還在執行中。我終止SQL執行。

DELETE FROM TBL_AD_CLICK_LOG
  WHERE ctid NOT IN (SELECT MIN(ctid)
                        FROM TBL_AD_CLICK_LOG
                       GROUP BY ES_APP_ID, IDFA_SUM);

優化的目的:用最小的時間達到相同效果。

  因此先在Oracle去執行;在用ora2pg工具遷移到PostgreSQL;我沒意見;比較相比前面花的時間要少。在PostgreSQL有沒有更高效的SQL呢?答案是有的

 delete from tbl_ad_click_log
  where ctid = any(array(select citd
           from (select "row_number"() over(partition by es_app_id, idfa_sum order by id) as rn,ctid
                   from tbl_ad_click_log) as ad
          where ad.rn > 1));

  先別吐槽SQL更復雜;但效率真的很棒;執行只花8s就搞定

相關文章
相關標籤/搜索