関数ベースのインデックスを Oracle から Postgre に移行するSQL - AWS 規範ガイダンス

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

関数ベースのインデックスを Oracle から Postgre に移行するSQL

作成者: Veeranjaneyulu Grandhi (AWS) と Navakanth Talluri (AWS)

環境:本稼働

ソース: Oracle

ターゲット: PostgreSQL

R タイプ: リアーキテクト

ワークロード: Oracle

テクノロジー: 移行、データベース

[概要]

インデックスはデータベースのパフォーマンスを向上させる一般的な方法です。インデックスを使用すると、データベースサーバーはインデックスがない場合よりもずっと速く特定の行を検索して取得できます。ただし、インデックスはデータベースシステム全体にオーバーヘッドも発生させるため、適切に使用する必要があります。関数または式に基づく関数ベースのインデックスには、複数の列や数式が含まれる場合があります。関数ベースのインデックスは、インデックス式を使用するクエリのパフォーマンスを向上させます。 

ネイティブでは、PostgreSQL は、ボラティリティが安定として定義されている関数を使用した関数ベースのインデックスの作成をサポートしていません。ただし、IMMUTABLE としてのボラティリティを持つ関数を作成して、インデックスの作成に使用することはできます。

IMMUTABLE 関数はデータベースを変更することはできず、同じ引数が与えられてもずっと同じ結果を返すことが保証されています。このカテゴリにより、クエリが定数引数で関数を呼び出したときに、オプティマイザーは関数を事前評価できます。 

このパターンは、to_char、、 などの関数とともに使用する場合にto_date、Oracle 関数ベースのインデックスto_numberを PostgreSQL の同等の に移行するのに役立ちます。

前提条件と制限

前提条件

  • アクティブな Amazon Web Services (AWS) アカウント

  • リスナーサービスがセットアップされて実行されているソース Oracle データベースインスタンス

  • PostgreSQL データベースに精通している

制約事項

  • データベースのサイズ制限は 64 TB です。

  • インデックスの作成に使用される関数は である必要がありますIMMUTABLE。

製品バージョン

  • バージョン 11g (バージョン 11.2.0.3.v1 以降) および、12.2 および 18c までのすべての Oracle データベースエディション

  • PostgreSQL バージョン 9.6 以降

アーキテクチャ

ソーステクノロジースタック

  • オンプレミスまたは Amazon Elastic Compute Cloud (Amazon EC2) インスタンス上の Oracle データベース、または Amazon RDS for Oracle DB インスタンス

ターゲットテクノロジースタック

  • PostgreSQL エンジン

ツール

  • pgAdmin 4 は Postgres 用のオープンソース管理ツールです。 pgAdmin 4 ツールは、データベースオブジェクトを作成、維持、使用するためのグラフィカルインターフェイスを提供します。

  • Oracle SQL Developer は、従来のデプロイとクラウドデプロイの両方で Oracle Database を開発および管理するための統合開発環境 (IDE) です。

エピック

タスク説明必要なスキル
to_char 関数を使用して列に関数ベースのインデックスを作成する。

次のコードを使用して、関数を作成します。

postgres=# create table funcindex( col1 timestamp without time zone); CREATE TABLE postgres=# insert into funcindex values (now()); INSERT 0 1 postgres=# select * from funcindex;             col1 ----------------------------  2022-08-09 16:00:57.77414 (1 rows)   postgres=# create index funcindex_idx on funcindex(to_char(col1,'DD-MM-YYYY HH24:MI:SS')); ERROR:  functions in index expression must be marked IMMUTABLE

 

注: PostgreSQL では、 IMMUTABLE句なしで関数ベースのインデックスを作成することはできません。

DBA、アプリデベロッパー
関数のボラティリティをチェックします。

関数のボラティリティをチェックするには、「追加情報」セクションのコードを使用してください。 

DBA
タスク説明必要なスキル
ラッパー関数を作成する。

ラッパー関数を作成するには、「追加情報」セクションのコードを使用してください。

PostgreSQL デベロッパー
ラッパー関数を使用してインデックスを作成します。

追加情報」セクションのコードを使用して、アプリケーションと同じスキーマにある IMMUTABLE キーワードを含むユーザー定義関数を作成し、索引作成スクリプトで参照します。

ユーザー定義の関数が (前の例の) 共通のスキーマで作成されている場合は、search_path を次のように更新します。

ALTER ROLE <ROLENAME> set search_path=$user, COMMON;
DBA、PostgreSQL デベロッパー
タスク説明必要なスキル
インデックス作成についての検証を行います。

クエリのアクセスパターンに基づき、インデックスの作成が必要であることを検証します。

DBA
インデックスが使用可能であることを検証します。

関数ベースのインデックスが PostgreSQL Optimizer によって取得されているかどうかを確認するには、 explain または explain analyze を使用してSQLステートメントを実行します。「追加情報」セクションのコードを使用してください。可能であれば、テーブル統計情報も収集します。

注: 説明プランに気付いた場合、PostgreSQL オプティマイザは述語条件のために関数ベースのインデックスを選択しました。

DBA

関連リソース

追加情報

ラッパー関数を作成する

CREATE OR REPLACE FUNCTION myschema.to_char(var1 timestamp without time zone, var2 varchar) RETURNS varchar AS $BODY$ select to_char(var1, 'YYYYMMDD'); $BODY$ LANGUAGE sql IMMUTABLE;

ラッパー関数を使用してインデックスを作成する

postgres=# create function common.to_char(var1 timestamp without time zone, var2 varchar) RETURNS varchar AS $BODY$ select to_char(var1, 'YYYYMMDD'); $BODY$ LANGUAGE sql IMMUTABLE; CREATE FUNCTION postgres=# create index funcindex_idx on funcindex(common.to_char(col1,'DD-MM-YYYY HH24:MI:SS')); CREATE INDEX

関数のボラティリティをチェックする

SELECT DISTINCT p.proname as "Name",p.provolatile as "volatility" FROM pg_catalog.pg_proc p  LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace  LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang  WHERE n.nspname OPERATOR(pg_catalog.~) '^(pg_catalog)$' COLLATE pg_catalog.default AND p.proname='to_char'GROUP BY p.proname,p.provolatile ORDER BY 1;

インデックスが使用可能であることを検証する

explain analyze <SQL>     postgres=# explain select col1 from funcindex where common.to_char(col1,'DD-MM-YYYY HH24:MI:SS') = '09-08-2022 16:00:57';                                                        QUERY PLAN ------------------------------------------------------------------------------------------------------------------------  Index Scan using funcindex_idx on funcindex  (cost=0.42..8.44 rows=1 width=8)    Index Cond: ((common.to_char(col1, 'DD-MM-YYYY HH24:MI:SS'::character varying))::text = '09-08-2022 16:00:57'::text) (2 rows)