

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Migre índices baseados em funções do Oracle para o PostgreSQL
<a name="migrate-function-based-indexes-from-oracle-to-postgresql"></a>

*Veeranjaneyulu Grandhi e Navakanth Talluri, Amazon Web Services*

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

Os índices são uma forma comum de aprimorar o desempenho do banco de dados. Um índice permite que o servidor do banco de dados encontre e recupere linhas específicas com muito mais rapidez do que poderia sem um índice. Mas os índices também adicionam sobrecarga ao sistema de banco de dados como um todo, portanto, devem ser usados com sensatez. Índices baseados em funções, baseados em uma função ou expressão, podem envolver várias colunas e expressões matemáticas. Um índice baseado em funções melhora o desempenho das consultas que usam a expressão de índice. 

Nativamente, o PostgreSQL não suporta a criação de índices baseados em funções usando funções que têm volatilidade definida como estável. No entanto, você pode criar funções semelhantes com volatilidade `IMMUTABLE` e usá-las na criação de índices.

Uma função `IMMUTABLE` não pode modificar o banco de dados e é garantido que retornará os mesmos resultados com os mesmos argumentos para sempre. Essa categoria permite que o otimizador pré-avalie a função quando uma consulta a chama com argumentos constantes. 

Esse padrão ajuda na migração dos índices baseados em funções do Oracle quando usados com funções como `to_char`, `to_date` e `to_number` para o equivalente do PostgreSQL.

## Pré-requisitos e limitações
<a name="migrate-function-based-indexes-from-oracle-to-postgresql-prereqs"></a>

**Pré-requisitos **
+ Uma conta ativa da Amazon Web Services (AWS)
+ Uma instância de banco de dados do Oracle de origem com o serviço de receptor configurado e em execução
+ Familiaridade com bancos de dados PostgreSQL

**Limitações**
+ O limite de tamanho do banco de dados é 64 TB.
+ As funções usadas na criação do índice devem ser IMUTÁVEIS.

**Versões do produto**
+ Todas as edições do banco de dados do Oracle para versões 11g (versões 11.2.0.3.v1 e posteriores) e até 12.2 e 18c
+ PostgreSQL, versões 9.6 e superiores

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

**Pilha de tecnologia de origem**
+ Um banco de dados Oracle no local ou em uma instância do Amazon Elastic Compute Cloud (Amazon EC2) ou uma instância de banco de dados Amazon RDS for Oracle

**Pilha de tecnologias de destino**
+ Qualquer mecanismo do PostgreSQL

## Ferramentas
<a name="migrate-function-based-indexes-from-oracle-to-postgresql-tools"></a>
+ O **pgAdmin 4** é uma ferramenta de gerenciamento de código aberto para o Postgres. A ferramenta pgAdmin 4 fornece uma interface gráfica para criar, manter e usar objetos de banco de dados.
+ O **Oracle SQL Developer** é um ambiente de desenvolvimento integrado (IDE) para desenvolver e gerenciar o Oracle Database em implantações tradicionais e na nuvem.

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

### Crie um índice baseado em funções usando uma função padrão
<a name="create-a-function-based-index-using-a-default-function"></a>


| Tarefa | Description | Habilidades necessárias | 
| --- | --- | --- | 
| Crie um índice baseado em função em uma coluna usando a função to\$1char. | Use o código a seguir para criar o índice baseado em função.<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> O PostgreSQL não permite a criação de um índice baseado em função sem a cláusula `IMMUTABLE`. | DBA, desenvolvedor de aplicativos | 
| Verifique a volatilidade da função. | Para verificar a volatilidade da função, use o código na seção *Informações adicionais*.   | DBA | 

### Crie índices baseados em funções usando uma função de encapsulamento
<a name="create-function-based-indexes-using-a-wrapper-function"></a>


| Tarefa | Description | Habilidades necessárias | 
| --- | --- | --- | 
| Crie uma função de encapsulamento. | Para criar uma função de encapsulamento, use o código na seção *Informações adicionais*. | Desenvolvedor do PostgreSQL | 
| Crie um índice usando a função de encapsulamento. | Use o código na seção *Informações adicionais* para criar uma função definida pelo usuário com a palavra-chave `IMMUTABLE` no mesmo esquema do aplicativo e faça referência a ela no script de criação de índice.Se uma função definida pelo usuário for criada em um esquema comum (do exemplo anterior), atualize o `search_path` conforme mostrado.<pre>ALTER ROLE <ROLENAME> set search_path=$user, COMMON;</pre> | DBA, desenvolvedor do PostgreSQL | 

### Validar a criação de um índice
<a name="validate-index-creation"></a>


| Tarefa | Description | Habilidades necessárias | 
| --- | --- | --- | 
| Valide a criação de um índice. | Valide se o índice precisa ser criado, com base nos padrões de acesso à consulta. | DBA | 
| Valide se o índice pode ser usado. | Para verificar se o índice baseado em função é captado pelo PostgreSQL Optimizer, execute uma instrução SQL usando explain (explicar) ou explain analyze (explicar e analizar). Use o código na seção *Informações adicionais*. Se possível, reúna também as estatísticas da tabela.Se você analisar o plano de explicabilidade, o otimizador do PostgreSQL selecionou um índice baseado em função em razão da condição do predicado. | DBA | 

## Recursos relacionados
<a name="migrate-function-based-indexes-from-oracle-to-postgresql-resources"></a>
+ [Índices baseados em funções](https://docs.oracle.com/cd/E11882_01/appdev.112/e41502/adfns_indexes.htm#ADFNS00505) (documentação da Oracle)
+ [Índices em expressões](https://www.postgresql.org/docs/9.4/indexes-expressional.html) (documentação do PostgreSQL)
+ [Volatilidade do PostgreSQL](https://www.postgresql.org/docs/current/xfunc-volatility.html) (documentação do PostgreSQL)
+ [PostgreSQL search\$1path](https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH) (documentação do PostgreSQL)
+ [Manual de migração do Oracle Database 19c para o PostgreSQL do Amazon Aurora](https://docs.aws.amazon.com/dms/latest/oracle-to-aurora-postgresql-migration-playbook/chap-oracle-aurora-pg.html) 

## Mais informações
<a name="migrate-function-based-indexes-from-oracle-to-postgresql-additional"></a>

**Crie uma função de encapsulamento**

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

**Crie um índice usando a função encapsulamento**

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

**Verifique a volatilidade da função**

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

**Valide se o índice pode ser usado**

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