將函數索引從Oracle遷移到PostgreSQL

2021-02-19 IT那活兒

我們使用AWSSchema ConversionTool(SCT)來轉換資料庫的元數據。通過AWS轉換後的腳本在PostgreSQL中執行,發現函數索引無法成功執行。

通過Oracle查詢發現其使用了substr和to_char等函數。

CREATE INDEX "HB_E2E"."IDX_CUST_ID_I" ON "HB_E2E"."FTP_DIPAN" (SUBSTR(TO_CHAR("CUST_ID"),-1))

而在PostgreSQL中執行則報ERROR: functions in index expression must be marked IMMUTABLE


手動執行上述函數,並不報錯。

根據PostgreSQL文檔,函數可以是3種類型,每一個函數都有一個易變性分類可能是VOLATILE、STABLE或者IMMUTABLE。如果CREATEFUNCTION命令沒有指定一個分類,則默認是VOLATILE。

通過查詢pg_proc,可以確認函數類型,例如sysdate函數。

SELECT proname, provolatile, proargtypes, proargtypes[0]::regtype AS argtype, prosrc FROM pg_proc WHERE proname like 『sysdate%』;

Provolatile為s,則說明是STABLE函數。

上述有點難以理解,我們來用案例實際說明一下。這裡使用current_timestamp來說明。

可以看到current_timestamp是的Provolatile狀態s,是STABLE函數。

STABLE函數不能修改資料庫,並且被確保對一個語句中的所有行用給定的相同參數返回相同的結果。

我們理解如下:

這個函數不能修改資料庫,它只能查詢時間。

並且被確保對一個語句中的所有行用給定的相同參數返回相同的結果。

這個是什麼意思呢?當你查一張大表,而這張表每一行要使用這個函數的時候,時間其實是在流逝的,但是你表上所有數據行都必須使用最開始的那個時間。(可以理解為事務開始的時間)。

我們來找類似的幾個時間函數測試一下。

除了clock_timestamp是VOLATILE,now和sysdate都是STABLE

我們創建一張表。

create table test_function

(

id         numeric,

now_time    timestamp without time zone,

sysdate_time timestamp without time zone,

clock_time  timestamp without time zone

);

插入10000行數據

insert into test_function

select generate_series(1,10000),now(),oracle.sysdate(),clock_timestamp();

插入完成後可以看到,當查詢這張表的時候,now(),oracle.sysdate()這種為STABLE的,時間不會發生變化,而clock_timestamp為VOLATILE類型則發生了變化。

至此,要創建函數索引,就必須把函數設置成IMMUTABLE。而實現辦法可以自己建一個IMMUTABLE函數,該函數接受輸入參數作為numeric類型。然後在創建函數索引的地方使用自己創建的。由於我這裡的函數索引使用了2種函數,一個是substr,一個是to_char,substr已經是IMMUTABLE的,所以只需要將to_char函數建成IMMUTABLE就行了。

CREATE OR REPLACE FUNCTION immutable_to_char(numeric) RETURNS character varying

AS

'select aws_oracle_ext.to_char($1)'

LANGUAGE SQL IMMUTABLE;

CREATE INDEX idx_cust_id_i ON hb_e2e.ftp_dipan USING BTREE (aws_oracle_ext.substr(immutable_to_char(cust_id::numeric),lengthb(immutable_to_char(cust_id::numeric)) ) ASC);

再次執行asc排序類的sql,發現已經可以使用這個函數索引了。

參考文檔:

函數穩定性講解- retalk PostgreSQL function's [volatile|stable|immutable ]

https://github.com/digoal/blog/blob/master/201212/20121226_01.md

MigratingFunction based indexes from Oracle to PostgreSQL

https://askdba.org/weblog/2018/01/migrating-function-based-indexes-from-oracle-to-postgresql/

相關焦點

  • PostgreSQL函數
    pl/pgsql 的設計目標是創建一種可加載的過程語言,可以用於創建函數和觸發器過程, 為sql語言增加控制結構, 執行複雜的計算。繼承所有用戶定義類型、函數、操作符, 定義為被伺服器信任的語言。pl/pgsql創建的函數可以在那些使用內置函數一樣的情形下使用。比如,可以創建複雜的條件計算函數,並隨後將之用於定義操作符或者用於函數索引中。
  • PostgreSQL初體驗
    隨後,在職業規劃上孫工又給了些建議,那就是多深入研究資料庫方面的知識,選擇一個資料庫sqlserver 、mysql 、postgres其中之一來深入,存續過程,索引,讀寫分離,資料庫調優,幾種樹的數據結構,B+樹。很感謝這半年的指導和建議,這些建議對我影響意義深遠。postgres這個名詞對我來說是頭一次聽說,隨後百度上查找了一些資料。
  • 如何將Oracle遷移至mysql?
    如果需要支持oracle連接,還需要配置OCI,選擇工具—選項—OCI,選擇對應路徑下文件:配置完成後關閉Navicat再重新打開。如果需要註冊,主目錄下key文件中有註冊碼。2)配置目的(mysql)資料庫連接輸入mysql連接信息3) 配置源(oracle)資料庫連接4)選擇工具-數據傳輸,配置源資料庫及目標資料庫,並選擇要傳輸的表在高級選項中可選擇只創建表,不同步記錄。也可以同時創建表和同步記錄。配置完成後點擊開始後進行轉換。
  • 時過境遷:Oracle跨平臺遷移之XTTS方案與實踐
    iot_type is not null;如果存在,目標端需要安裝 Patch 14835322,否則索引組織表的對象無法導入到目標端。目前該補丁只在 11.2.0.3 版本下提供,針對其他版本,如果 IOT表或者鍵值壓縮索引無法導入時,建議在元數據導入完成後,將該類對象傳輸過去。1.6.
  • PostgreSQL 自帶to_date函數挖了一個坑.
    遷移到 PostgreSQL無法查找數據啊?"這不是很容易嗎?數據肯定不一致啊,我心想道。「把 SQL發送過來看看吧!」只見她迅速丟出一個txt文本,打開的文本是一段長達200行 SQL代碼。那時候我就懵逼了,這要查數據不一致,真的要查很久啊。
  • PostgreSQL 12 首個版本說明草案發布
    對於從任意舊版本遷移到 PostgreSQL 12 的用戶,需要使用 pg_dumpall 或 pg_upgrade 進行 dump/restore(備份和恢復) 操作。 刪除數據類型abstime,reltime和tinterval 刪除時間段擴展(timetravel extension) 將recovery.conf設置移動至postgresql.conf
  • Oracle 資料庫遷移-百家號 - 百度經驗
    Oracle 資料庫遷移需求分析:資料庫所有文件(數據文件、日誌文件、臨時文件、控制文件)都存放在光纖存儲中,但是光纖存儲使用時間過長,超過3年,經常出現一些問題,而且光纖存儲需要廠家維護,維護方面不是很方便,需要將資料庫文件遷移到nas存儲中。
  • PostgreSQL簡介及安裝
    PostgreSQL 可以用許多方法擴展,比如,通過增加新的數據類型、函數、操作符、聚集函數、索引。(你可以在網際網路上找到更多的信息,這裡就不搬運了,以後再詳細聊聊PostgerSQL 的江湖地位。)1.
  • Oracle資料庫優化的一些建議
    ,索引的雙重效應,列的選擇性;(3)、編碼方面:利用索引,避免大表FULL TABLE SCAN;合理使用臨時表;避免寫過於複雜的sql,不一定非要一個sql解決問題;在不影響業務的前提下減小事務的粒度
  • Oracle|19C升級WM_CONCAT函數失效
    最近項目Oracle資料庫升級由11g升到19C,在驗證過程中發現wm_concat函數竟然失效了。
  • 去哪兒PostgreSQL指南
    , column, view, index, sequence, function, trigger等名稱:    (1) 建議使用小寫字母、數字、下劃線的組合。建議能用varchar(N) 就不用char(N),以利於節省存儲空間;3. 建議能用varchar(N) 就不用text,varchar;4. 建議使用default NULL,而不用default '',以節省存儲空間;5.
  • 舉一反三:跨平臺版本遷移之 XTTS 方案操作指南
    not supported due to Bug 12702521--在 11gR2 中,因為 Bug 12702521 的存在,Solaris SPARC (64-bit) <-> AIX (64-bit) 這2個版本之間不能進行 RMAN 操作。
  • PostgreSQL 13 正式發布 - OSCHINA - 中文開源技術交流社區
    性能提升在先前 PostgreSQL 版本的基礎上,PostgreSQL 13 可以有效地處理 B 樹索引(PostgreSQL 的標準索引)中的重複數據,從而降低 B 樹索引所需的整體空間使用率,同時提高了整體查詢性能。PostgreSQL 13 引入了增量排序,即在查詢中較早步驟的排序數據可以加速後面步驟的排序。
  • 滲透中利用postgresql getshell及注入技巧
    所以本人打算將公開課資源分成8個小部分給大家學習,目前總大小250G 左右,都是優質資源,夠你白嫖了吧領取方法:後臺回復關鍵詞「大佬您好」即可獲得!3.B站在線學習連結由於分享的資源連結經常被和諧,所以必須遷移到B站上供大家學習B站up主官方帳號:VMYKnetwork團隊0x00 前言研究postgresql資料庫如何getshell是在滲透中遇到一個pgAdmin的web管理頁面可以直接操作postgresql且通過網上的文章沒有達到9.6版本getshell的效果所以便有了以下文章。
  • 聊聊oracle+hint 的使用
    oracle也會犯犯傻,會幫我們選擇非常不好的執行計劃,這個時候就需要我們來手工的優化優化,幫助oracle 提高下運行效率。,這時候oracle中的收集表統計信息的功能大部分是被dba關掉的,所以這就很容易造成一種情況就是oracle根據表統計信息選擇執行計劃的時候,由於表統計信息過於老舊,oracle會選擇一個錯誤的執行計劃。
  • Oracle 資料庫備份與恢復總結-exp/imp (導出與導入裝庫與卸庫)
    三種模式 (1)表方式,將指定表的數據導出/導入。      目標資料庫不能有與遷移表空間同名的表空間?      SYS 的對象不能遷移?      有一些對象,如物化視圖,基於函數的索引等不能被傳輸(同字節序文件的跨平臺可以用更換數據文件的文件頭的方法)(10g  支持跨平臺的表空間傳輸,只要作業系統字節順序相同,就可以進行表空間
  • PostgreSQL Tips: 動態SQL
    前言前幾天 Postgres 群裡有人問如何在 Postgres 裡實現動態列的行轉列,於是我整理了PostgreSQL 實現動態行轉列的方法匯總然後被問到如何直接通過一個函數返回結果,而不是返回一個待執行的 SQL 語句,於是我參考下面的教程,實現了一個函數返回 json,先把代碼附上
  • PostgreSQL 10 新增特性
    (點擊上方公眾號,可快速關注)來源:oschinawww.oschina.net/news/83681/new-features-coming-in-postgresql
  • Oracle新聞
    今天甲骨文中國正式發布公告來告知雙方合作的內容:微軟和甲骨文近日宣布建立合作夥伴關係,這將能讓客戶在Windows Server Hyper…10-29在今年的Oracle OpenWorld大會上,來自英特爾的副總裁Diane Bryant在演講中稱傳統IT與雲計算之間的界限將逐漸模糊,未來的數據將更多地存儲在雲中,所有的網絡也將相互連通,並且能夠…
  • 阿里雲如何打破Oracle 遷移上雲的壁壘
    本文提出了Oracle 到雲資料庫PPAS遷移的方案,這種遷移方案為什麼比Oracle到 MySQL系列的遷移容易推動呢?答案即將揭曉。  Oracle資料庫遷移方案在這個解決方案中,用戶可以通過不同的方式,將資料庫遷移到雲上,我們可以繼續在ECS中運行Oracle,也可以遷移到MySQL。當然也可以將應用及資料庫系統遷移到雲資料庫PPAS版,藉助其高度兼容Oracle的能力,降低用戶遷移上雲的難度,並降低系統長期運維的複雜性。