

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Migrieren Sie funktionsbasierte Indizes von Oracle nach PostgreSQL
<a name="migrate-function-based-indexes-from-oracle-to-postgresql"></a>

*Veeranjaneyulu Grandhi und Navakanth Talluri, Amazon Web Services*

## Zusammenfassung
<a name="migrate-function-based-indexes-from-oracle-to-postgresql-summary"></a>

Indizes sind eine gängige Methode zur Verbesserung der Datenbankleistung. Ein Index ermöglicht es dem Datenbankserver, bestimmte Zeilen viel schneller zu finden und abzurufen, als dies ohne einen Index möglich wäre. Indizes erhöhen jedoch auch den Mehraufwand für das Datenbanksystem als Ganzes, weshalb sie sinnvoll verwendet werden sollten. Funktionsbasierte Indizes, die auf einer Funktion oder einem Ausdruck basieren, können mehrere Spalten und mathematische Ausdrücke beinhalten. Ein funktionsbasierter Index verbessert die Leistung von Abfragen, die den Indexausdruck verwenden. 

PostgreSQL unterstützt nativ nicht die Erstellung funktionsbasierter Indizes mit Funktionen, deren Volatilität als stabil definiert ist. Sie können jedoch ähnliche Funktionen mit Volatilität erstellen `IMMUTABLE` und sie bei der Indexerstellung verwenden.

Eine `IMMUTABLE` Funktion kann die Datenbank nicht ändern, und es ist garantiert, dass sie bei denselben Argumenten für immer dieselben Ergebnisse zurückgibt. Diese Kategorie ermöglicht es dem Optimierer, die Funktion vorab auszuwerten, wenn eine Abfrage sie mit konstanten Argumenten aufruft. 

Dieses Muster hilft bei der Migration der funktionsbasierten Oracle-Indizes, wenn sie mit Funktionen wie `to_char``to_date`, und `to_number` zum PostgreSQL-Äquivalent verwendet werden.

## Voraussetzungen und Einschränkungen
<a name="migrate-function-based-indexes-from-oracle-to-postgresql-prereqs"></a>

**Voraussetzungen**
+ Ein aktives Amazon Web Services (AWS) -Konto
+ Eine Oracle-Quelldatenbank-Instance, auf der der Listener-Service eingerichtet ist und läuft
+ Vertrautheit mit PostgreSQL-Datenbanken

**Einschränkungen**
+ Die maximale Datenbankgröße beträgt 64 TB.
+ Die bei der Indexerstellung verwendeten Funktionen müssen UNVERÄNDERLICH sein.

**Produktversionen**
+ Alle Oracle-Datenbankeditionen für die Versionen 11g (Versionen 11.2.0.3.v1 und höher) und bis zu 12.2 und 18c
+ PostgreSQL-Versionen 9.6 und höher

## Architektur
<a name="migrate-function-based-indexes-from-oracle-to-postgresql-architecture"></a>

**Quelltechnologie-Stack**
+ Eine Oracle-Datenbank vor Ort oder auf einer Amazon Elastic Compute Cloud (Amazon EC2) -Instance oder eine Amazon RDS for Oracle DB-Instance

**Zieltechnologie-Stack**
+ Beliebige PostgreSQL-Engine

## Tools
<a name="migrate-function-based-indexes-from-oracle-to-postgresql-tools"></a>
+ **pgAdmin 4** ist ein Open-Source-Verwaltungstool für Postgres. Das Tool pgAdmin 4 bietet eine grafische Oberfläche zum Erstellen, Verwalten und Verwenden von Datenbankobjekten.
+ **Oracle SQL Developer** ist eine integrierte Entwicklungsumgebung (IDE) für die Entwicklung und Verwaltung von Oracle Database sowohl in herkömmlichen als auch in Cloud-Bereitstellungen.

## Epen
<a name="migrate-function-based-indexes-from-oracle-to-postgresql-epics"></a>

### Erstellen Sie einen funktionsbasierten Index mit einer Standardfunktion
<a name="create-a-function-based-index-using-a-default-function"></a>


| Aufgabe | Description | Erforderliche Fähigkeiten | 
| --- | --- | --- | 
| Erstellen Sie mit der Funktion to\$1char einen funktionsbasierten Index für eine Spalte. | Verwenden Sie den folgenden Code, um den funktionsbasierten Index zu erstellen.<pre>postgres=# create table funcindex( col1 timestamp without time zone);<br />CREATE TABLE<br />postgres=# insert into funcindex values (now());<br />INSERT 0 1<br />postgres=# select * from funcindex;<br />            col1<br />----------------------------<br /> 2022-08-09 16:00:57.77414<br />(1 rows)<br /> <br />postgres=# create index funcindex_idx on funcindex(to_char(col1,'DD-MM-YYYY HH24:MI:SS'));<br />ERROR:  functions in index expression must be marked IMMUTABLE</pre> PostgreSQL erlaubt es nicht, einen funktionsbasierten Index ohne die Klausel zu erstellen. `IMMUTABLE` | DBA, App-Entwickler | 
| Überprüfen Sie die Volatilität der Funktion. | Verwenden Sie den Code im Abschnitt *Zusätzliche Informationen*, um die Volatilität der Funktion zu überprüfen.   | DBA | 

### Erstellen Sie funktionsbasierte Indizes mithilfe einer Wrapper-Funktion
<a name="create-function-based-indexes-using-a-wrapper-function"></a>


| Aufgabe | Description | Erforderliche Fähigkeiten | 
| --- | --- | --- | 
| Erstellen Sie eine Wrapper-Funktion. | Verwenden Sie den Code im Abschnitt *Zusätzliche Informationen*, um eine Wrapper-Funktion zu erstellen. | PostgreSQL-Entwickler | 
| Erstellen Sie einen Index mithilfe der Wrapper-Funktion. | Verwenden Sie den Code im Abschnitt *Zusätzliche Informationen*, um eine benutzerdefinierte Funktion mit dem Schlüsselwort `IMMUTABLE` im selben Schema wie die Anwendung zu erstellen, und verweisen Sie im Skript zur Indexerstellung darauf.Wenn eine benutzerdefinierte Funktion in einem gemeinsamen Schema (aus dem vorherigen Beispiel) erstellt wird, aktualisieren Sie diese wie gezeigt. `search_path`<pre>ALTER ROLE <ROLENAME> set search_path=$user, COMMON;</pre> | DBA, PostgreSQL-Entwickler | 

### Überprüfen Sie die Indexerstellung
<a name="validate-index-creation"></a>


| Aufgabe | Description | Erforderliche Fähigkeiten | 
| --- | --- | --- | 
| Überprüfen Sie die Indexerstellung. | Stellen Sie sicher, dass der Index auf der Grundlage von Abfragezugriffsmustern erstellt werden muss. | DBA | 
| Stellen Sie sicher, dass der Index verwendet werden kann. | Um zu überprüfen, ob der funktionsbasierte Index vom PostgreSQL Optimizer übernommen wird, führen Sie eine SQL-Anweisung mit explain oder explain analyze aus. *Verwenden Sie den Code im Abschnitt Zusätzliche Informationen.* Sammeln Sie nach Möglichkeit auch die Tabellenstatistiken.Wenn Sie den Explain-Plan bemerken, hat der PostgreSQL-Optimierer aufgrund der Prädikatbedingung einen funktionsbasierten Index ausgewählt. | DBA | 

## Zugehörige Ressourcen
<a name="migrate-function-based-indexes-from-oracle-to-postgresql-resources"></a>
+ [Funktionsbasierte Indizes (Oracle-Dokumentation](https://docs.oracle.com/cd/E11882_01/appdev.112/e41502/adfns_indexes.htm#ADFNS00505))
+ [Indizes für Ausdrücke](https://www.postgresql.org/docs/9.4/indexes-expressional.html) (PostgreSQL-Dokumentation)
+ [PostgreSQL-Volatilität](https://www.postgresql.org/docs/current/xfunc-volatility.html) (PostgreSQL-Dokumentation)
+ [PostgreSQL search\$1path](https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH) (PostgreSQL-Dokumentation)
+ [Leitfaden für die Migration von Oracle Database 19c zu Amazon Aurora PostgreSQL](https://docs.aws.amazon.com/dms/latest/oracle-to-aurora-postgresql-migration-playbook/chap-oracle-aurora-pg.html) 

## Zusätzliche Informationen
<a name="migrate-function-based-indexes-from-oracle-to-postgresql-additional"></a>

**Erstellen Sie eine Wrapper-Funktion**

```
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;
```

**Erstellen Sie einen Index mithilfe der Wrapper-Funktion**

```
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
```

**Überprüfen Sie die Volatilität der Funktion**

```
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;
```

**Stellen Sie sicher, dass der Index verwendet werden kann**

```
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)
```