

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á.

# Limpeza e análise manual de tabelas
<a name="manual-vacuum"></a>

Se seu banco de dados for limpo pelo processo de autovacuum, é uma prática recomendada evitar a execução de verificações manuais em todo o banco de dados com muita frequência. Uma aspiração manual pode resultar em I/O cargas desnecessárias ou picos de CPU e também pode falhar na remoção de tuplas mortas. Execute aspiradores manuais somente table-by-table se for realmente necessário, como quando a proporção de tuplas vivas e mortas é baixa ou quando há longos espaços entre os aspiradores automáticos. Além disso, você deve executar aspiradores manuais quando a atividade do usuário for mínima.

O autovacuum também mantém as estatísticas de uma tabela atualizadas. Quando você executa o comando `ANALYZE` manualmente, ele recria essas estatísticas em vez de atualizá-las. A recriação de estatísticas quando elas já estão atualizadas pelo processo normal de autovacuum pode resultar na utilização de recursos do sistema.

Recomendamos que você execute os comandos [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html) e [ANALYZE](https://www.postgresql.org/docs/current/sql-analyze.html) manualmente nos seguintes cenários: 
+ Durante horários de baixo pico em tabelas mais movimentadas, quando a limpeza automática pode não ser suficiente.
+ Imediatamente depois de carregar dados em massa na tabela de destino. Nesse caso, executar `ANALYZE` manualmente recria completamente as estatísticas, o que é uma opção melhor do que esperar o início do autovacuum.
+ Para limpar tabelas temporárias (o autovacuum não pode acessá-las).

Para reduzir o I/O impacto ao executar os `ANALYZE` comandos `VACUUM` e na atividade simultânea do banco de dados, você pode usar o `vacuum_cost_delay` parâmetro. Em muitas situações, comandos de manutenção como `VACUUM` e `ANALYZE` não precisam ser concluídos rapidamente. No entanto, esses comandos não devem interferir na capacidade do sistema de realizar outras operações de banco de dados. Para evitar isso, você pode habilitar atrasos de vacuum baseados em custos usando o parâmetro `vacuum_cost_delay`. Por padrão, esse parâmetro é desabilitado para comandos `VACUUM` emitidos manualmente. Para habilitá-lo, defina-o com um valor diferente de zero.

## Execução de operações de vacuum e limpeza em paralelo
<a name="manual-vacuum-parallel"></a>

A opção [PARALLEL](https://www.postgresql.org/docs/current/sql-vacuum.html) do comando `VACUUM` usa operadores paralelos para as fases de vacuum e limpeza do índice e está desabilitada por padrão. O número de operadores paralelos (o grau de paralelismo) é determinado pelo número de índices na tabela e pode ser especificado pelo usuário. Se você estiver executando operações `VACUUM` paralelas sem um argumento inteiro, o grau de paralelismo será calculado com base no número de índices na tabela.

Os parâmetros a seguir ajudam você a configurar a operação de vacuum paralela no Amazon RDS para PostgreSQL e no Aurora compatível com PostgreSQL:
+ [max\$1worker\$1processes](https://www.postgresql.org/docs/current/runtime-config-resource.html) define o número máximo de processos de operadores simultâneos.
+ [min\$1parallel\$1index\$1scan\$1size](https://www.postgresql.org/docs/current/runtime-config-query.html) define a quantidade mínima de dados de índice que devem ser verificados para que uma verificação paralela seja considerada.
+ [max\$1parallel\$1maintenance\$1workers](https://www.postgresql.org/docs/current/runtime-config-resource.html) define o número máximo de operadores paralelos que podem ser iniciados por um único comando de utilitário.

**nota**  
A opção `PARALLEL` é usada somente para fins de limpeza. Não afeta o comando `ANALYZE`.

O exemplo a seguir ilustra o comportamento do banco de dados quando você usa o `VACUUM` e `ANALYZE` manuais em um banco de dados.

Confira um exemplo de tabela em que o autovacuum foi desabilitado (apenas para fins ilustrativos; desabilitar o autovacuum não é recomendado):

```
create table t1 ( a int, b int, c int );
alter table t1 set (autovacuum_enabled=false);
```

```
apgl=> \d+ t1
Table "public.t1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------
a | integer | | | | plain | |
b | integer | | | | plain | |
c | integer | | | | plain | |
Access method: heap
Options: autovacuum_enabled=false
```

Adicionar 1 milhão de linhas à tabela t1:

```
apgl=> select count(*) from t1;
count
1000000
(1 row)
```

Estatísticas da tabela t1:

```
select * from pg_stat_all_tables where relname='t1';
-[ RECORD 1 ]-------+--------
relid         | 914744
schemaname    | public
relname       | t1
seq_scan      | 0
seq_tup_read  | 0
idx_scan      |
idx_tup_fetch |
n_tup_ins     | 1000000
n_tup_upd     | 0
n_tup_del     | 0
n_tup_hot_upd | 0
n_live_tup    | 1000000
n_dead_tup    | 0
n_mod_since_analyze | 1000000
last_vacuum      |
last_autovacuum  |
last_analyze     |
last_autoanalyze |
vacuum_count     | 0
autovacuum_count | 0
analyze_count    | 0
autoanalyze_count | 0
```

Adicionar um índice:

```
create index i2 on t1 (b,a);
```

Execute o comando `EXPLAIN` (Plano 1):

```
Bitmap Heap Scan on t1 (cost=10521.17..14072.67 rows=5000 width=4)
Recheck Cond: (a = 5)
→ Bitmap Index Scan on i2 (cost=0.00..10519.92 rows=5000 width=0)
Index Cond: (a = 5)
(4 rows)
```

Execute o comando `EXPLAIN ANALYZE` (Plano 2):

```
explain (analyze,buffers,costs off) select a from t1 where b = 5;
QUERY PLAN
Bitmap Heap Scan on t1 (actual time=0.023..0.024 rows=1 loops=1)
Recheck Cond: (b = 5)
Heap Blocks: exact=1
Buffers: shared hit=4
→ Bitmap Index Scan on i2 (actual time=0.016..0.016 rows=1 loops=1)
Index Cond: (b = 5)
Buffers: shared hit=3
Planning Time: 0.054 ms
Execution Time: 0.076 ms
(9 rows)
```

Os comandos `EXPLAIN ` e `EXPLAIN ANALYZE ` exibem planos diferentes, porque o autovacuum foi desabilitado na tabela e o comando `ANALYZE` não foi executado manualmente. Agora vamos atualizar um valor na tabela e regenerar o plano `EXPLAIN ANALYZE`:

```
update t1 set a=8 where b=5;
explain (analyze,buffers,costs off) select a from t1 where b = 5;
```

O comando `EXPLAIN ANALYZE` (Plano 3) agora exibe:

```
apgl=> explain (analyze,buffers,costs off) select a from t1 where b = 5;
QUERY PLAN
Bitmap Heap Scan on t1 (actual time=0.075..0.076 rows=1 loops=1)
Recheck Cond: (b = 5)
Heap Blocks: exact=1
Buffers: shared hit=5
→ Bitmap Index Scan on i2 (actual time=0.017..0.017 rows=2 loops=1)
Index Cond: (b = 5)
Buffers: shared hit=3
Planning Time: 0.053 ms
Execution Time: 0.125 ms
```

Se você comparar os custos entre o Plano 2 e o Plano 3, verá as diferenças no tempo de planejamento e execução, porque ainda não coletamos estatísticas.

Agora vamos executar um `ANALYZE` manual na tabela, verificar as estatísticas e regenerar o plano:

```
apgl=> analyze t1
apgl→ ;
ANALYZE
Time: 212.223 ms

apgl=> select * from pg_stat_all_tables where relname='t1';
-[ RECORD 1 ]-------+------------------------------
relid          | 914744
schemaname     | public
relname        | t1
seq_scan       | 3
seq_tup_read   | 1000000
idx_scan       | 3
idx_tup_fetch  | 3
n_tup_ins      | 1000000
n_tup_upd      | 1
n_tup_del      | 0
n_tup_hot_upd  | 0
n_live_tup     | 1000000
n_dead_tup     | 1
n_mod_since_analyze | 0
last_vacuum       |
last_autovacuum   |
last_analyze      | 2023-04-15 11:39:02.075089+00
last_autoanalyze  |
vacuum_count      | 0
autovacuum_count  | 0
analyze_count     | 1
autoanalyze_count | 0

Time: 148.347 ms
```

Execute o comando `EXPLAIN ANALYZE` (Plano 4):

```
apgl=> explain (analyze,buffers,costs off) select a from t1 where b = 5;
QUERY PLAN
Index Only Scan using i2 on t1 (actual time=0.022..0.023 rows=1 loops=1)
Index Cond: (b = 5)
Heap Fetches: 1
Buffers: shared hit=4
Planning Time: 0.056 ms
Execution Time: 0.068 ms
(6 rows)

Time: 138.462 ms
```

Se comparar todos os resultados do plano depois de analisar manualmente a tabela e coletar estatísticas, você observará que o Plano 4 do otimizador é melhor do que os outros e que também diminui o tempo de execução da consulta. Este exemplo mostra como é importante executar atividades de manutenção no banco de dados.

## Reescrita de toda uma tabela com VACUUM FULL
<a name="manual-vacuum-full"></a>

A execução do comando `VACUUM ` com o parâmetro `FULL` regrava todo o conteúdo de uma tabela em um novo arquivo de disco sem espaço extra e retorna espaço não utilizado para o sistema operacional. Essa operação é muito mais lenta e requer um bloqueio `ACCESS EXCLUSIVE` em cada tabela. Também requer espaço extra em disco, pois grava uma nova cópia da tabela e não libera a cópia antiga até que a operação seja concluída. 

O `VACUUM FULL` pode ser útil nos seguintes casos:** **
+ Quando você quiser recuperar uma volume significativo de espaço nas tabelas. 
+ Quando você quiser recuperar espaço inchado em tabelas de chaves não primárias.

Recomendamos que você use `VACUUM FULL` quando tiver tabelas de chaves não primárias, se seu banco de dados puder tolerar tempo de inatividade.

Como o `VACUUM FULL` requer mais bloqueio do que outras operações, é mais caro executá-lo em bancos de dados cruciais. Para substituir esse método, você pode usar a extensão `pg_repack `, descrita na [próxima seção](pg-repack.md). Essa opção é semelhante ao `VACUUM FULL`, mas requer bloqueio mínimo e é compatível com o Amazon RDS para PostgreSQL e o Aurora compatível com PostgreSQL.