adsas 數據庫是用於廣告買量數據分析;在17年由 Oracle 遷移到 PostgreSQL。現把以前的遷移筆記整理下。本次遷移表91個;存儲過程21個;數據庫大小2G。 html
安裝PostgreSQL數據庫 參考 PostgreSQL簡單安裝手冊 ; sql
在安裝PostgreSQL數據庫以前;首先要對數據庫硬件要作基準評測;會影響是否能取代Oracle服務器。安裝完成以後;須要建立同名 數據庫/用戶/schema。數據庫
Ora2Pg是一個免費的工具,用於將Oracle數據庫遷移到PostgreSQL兼容的模式。它鏈接您的Oracle數據庫,自動掃描並提取它的結構或數據,而後生成能夠裝載到PostgreSQL數據庫的SQL腳本。Ora2Pg能夠從逆向工程Oracle數據庫到大型企業數據庫遷移,或者簡單地將一些Oracle數據複製到PostgreSQL數據庫中。它很是容易使用,而且不須要任何Oracle數據庫知識,而不須要提供鏈接到Oracle數據庫所需的參數。服務器
安裝配置文檔架構
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)
app
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
dom
參數配置查考函數
[postgres@oracle166 config]$ ora2pg -c ora2pg.conf
[postgres@oracle166 ]$ psql adsas adsas psql (9.6.0) Type "help" for help. adsas=> \i /home/postgres/config/adsas.sql
工具
在改寫存儲過程/函數以前;先安裝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
這個我感受沒多大用;能夠忽略!
A/G
經存儲過程/函數改寫完成;代碼要跟Oracle等同;執行時長跟Oracle上面的時長是否差很少;發如今Oracle上面執行 12s;而改寫的代碼須要 256s;相差21倍之多。這差距不是通常的大。一樣的代碼可能在Oracle執行效果要好;這跟數據庫底層代碼有關。
經覈查;其中有條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還短。
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);
優化的目的:用最小的時間達到相同效果。
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));