

 O Amazon Redshift não permitirá mais a criação de UDFs do Python a partir do Patch 198. As UDFs do Python existentes continuarão a funcionar normalmente até 30 de junho de 2026. Para ter mais informações, consulte a [publicação de blog ](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

# Distribuição de dados para otimização de consultas
<a name="t_Distributing_data"></a>

Quando você carrega dados em uma tabela, o Amazon Redshift distribui as linhas da tabela para cada um dos nós de computação de acordo com o estilo de distribuição da tabela. Quando você executa uma consulta, o otimizador de consulta redistribui as linhas aos nós de computação conforme necessário para executar junções e agregações. O objetivo de escolher um estilo de distribuição de tabela é minimizar o impacto da etapa de redistribuição ao localizar os dados onde eles precisam estar antes que a consulta seja executada.

**nota**  
Esta seção apresentará os princípios de distribuição de dados em um banco de dados do Amazon Redshift. Recomendamos que você crie suas tabelas com `DISTSTYLE AUTO`. Se você fizer isso, o Amazon Redshift usará a otimização automática de tabela para escolher o estilo de distribuição de dados. Para obter mais informações, consulte [Otimização automática de tabelas](t_Creating_tables.md). O restante desta seção fornece detalhes sobre estilos de distribuição. 

**Topics**
+ [Conceitos de distribuição de dados](#t_data_distribution_concepts)
+ [Estilos de distribuição](c_choosing_dist_sort.md)
+ [Visualização dos estilos de distribuição](viewing-distribution-styles.md)
+ [Avaliação dos padrões de consulta](t_evaluating_query_patterns.md)
+ [Designação de estilos de distribuição](t_designating_distribution_styles.md)
+ [Avaliação do plano de consulta](c_data_redistribution.md)
+ [Exemplo de plano de consulta](t_explain_plan_example.md)
+ [Exemplos de distribuição](c_Distribution_examples.md)

## Conceitos de distribuição de dados
<a name="t_data_distribution_concepts"></a>

Seguem-se alguns conceitos de distribuição de dados para o Amazon Redshift.

 **Nós e fatias** 

 Um cluster do Amazon Redshift é um conjunto de nós. Cada nó no cluster tem seu próprio sistema operacional, memória dedicada e armazenamento de disco dedicado. Um dos nós é o *nó líder*, que gerencia a distribuição de dados e tarefas de processamento de consultas aos nós de computação. Os *nós de computação* fornecem recursos para realizar essas tarefas. 

 O armazenamento de disco para um nó de computação é dividido em um número de *fatias*. O número de fatias por nó depende do tamanho do nó do cluster. Todos os nós participam da execução de consultas paralelas, trabalhando nos dados que são distribuídos da maneira mais uniforme possível pelas fatias. Para obter mais informações sobre o número de fatias que cada tamanho de nó possui, consulte “[Clusters e nós no Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#rs-about-clusters-and-nodes)” no *Guia de gerenciamento de clusters do Amazon Redshift*.

 **Redistribuição de dados** 

 Quando você carrega dados em uma tabela, o Amazon Redshift distribui as linhas da tabela para cada uma das fatias de nó de acordo com o estilo de distribuição da tabela. Como parte de um plano de consulta, o otimizador determina onde os blocos de dados precisam estar localizados para melhor executar a consulta. Então, os dados são movidos fisicamente, ou redistribuídos, enquanto a consulta é executada. A redistribuição pode envolver o envio de linhas específicas aos nós para junção ou a transmissão de uma tabela inteira para todos os nós. 

 A redistribuição de dados pode representar uma parcela substancial do custo de um plano de consulta e o tráfego de rede que ela gera pode afetar outras operações de banco de dados e retardar a performance geral do sistema. Na medida em que você antecipa onde melhor localizar os dados inicialmente, é possível minimizar o impacto da redistribuição de dados. 

 **Metas da distribuição de dados** 

 Quando você carrega dados em uma tabela, o Amazon Redshift distribui as linhas da tabela para os nós de computação e fatias de acordo com o estilo de distribuição que você escolheu ao criar a tabela. A distribuição de dados tem duas metas principais: 
+ Para distribuir uniformemente o workload entre os nós no cluster. A distribuição desigual, ou desvio de distribuição de dados, força alguns nós a trabalhar mais do que outros, o que afeta a performance da consulta.
+ Para minimizar a movimentação de dados conforme uma consulta é executada. Se as linhas que participam de junções ou agregações já estão colocadas nos nós com suas linhas de junção em outras tabelas, o otimizador não precisa redistribuir tantos dados quando as consultas são executadas.

A estratégia de distribuição escolhida para seu banco de dados tem consequências importantes para a performance da consulta, requisitos de armazenamento, carregamento de dados e manutenção. Com a escolha do melhor estilo de distribuição para cada tabela, você pode equilibrar sua distribuição de dados e melhorar a performance geral do sistema.

# Estilos de distribuição
<a name="c_choosing_dist_sort"></a>

Ao criar uma tabela, é possível determinar um destes quatro estilos de distribuição; AUTO, EVEN, KEY ou ALL. 

Se você não especificar um estilo de distribuição, o Amazon Redshift usa distribuição AUTO.

 **Distribuição AUTO** 

Com a distribuição AUTO, o Amazon Redshift atribui um estilo de distribuição ideal com base no tamanho dos dados da tabela. Por exemplo, se o estilo de distribuição AUTO for especificado, o Amazon Redshift inicialmente vai atribuir o estilo de distribuição ALL a uma tabela pequena. Quando a tabela crescer, o Amazon Redshift poderá alterar o estilo de distribuição para KEY, escolhendo a chave primária (ou uma coluna da chave primária composta) como chave de distribuição. Se a tabela crescer e nenhuma das colunas for adequada para ser a chave de distribuição, o Amazon Redshift vai alterar o estilo de distribuição para EVEN. A mudança no estilo de distribuição ocorre em segundo plano com impacto mínimo nas consultas do usuário. 

Para visualizar ações que o Amazon Redshift executou automaticamente para alterar uma chave de distribuição de tabela, consulte [SVL\$1AUTO\$1WORKER\$1ACTION](r_SVL_AUTO_WORKER_ACTION.md). Para exibir as recomendações atuais sobre a alteração de uma chave de distribuição de tabela, consulte [SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS](r_SVV_ALTER_TABLE_RECOMMENDATIONS.md). 

Para visualizar o estilo de distribuição aplicado a uma tabela, consulte a exibição de catálogo de sistema PG\$1CLASS\$1INFO. Para obter mais informações, consulte [Visualização dos estilos de distribuição](viewing-distribution-styles.md). Se você não especificar um estilo de distribuição com a instrução CREATE TABLE, o Amazon Redshift aplicará a distribuição AUTO. 

 **Distribuição EVEN** 

 O nó de liderança distribui as linhas ao longo das fatias de modo round-robin, independente dos valores de qualquer coluna específica. A distribuição EVEN é apropriada quando uma tabela não participa de junções. Também é apropriado quando não há uma opção clara entre a distribuição KEY e ALL.

 **Distribuição KEY** 

 As linhas são distribuídas de acordo com os valores em uma coluna. O nó líder coloca os valores correspondentes na mesma fatia do nó. Se você distribuir um par de tabelas nas chaves de união, o nó líder coloca as linhas nas fatias de acordo com os valores nas colunas de união. Desta forma, os valores correspondentes das colunas comuns são armazenados fisicamente juntos. 

 **Distribuição ALL** 

 Uma cópia de toda a tabela é distribuída para cada nó. Onde a distribuição EVEN ou a distribuição KEY coloca apenas uma porção das linhas da tabela em cada nó, a distribuição ALL garante que todas as linhas sejam dispostas para cada junção na qual a tabela participa. 

 A distribuição ALL multiplica o armazenamento exigido pelo número de nós no cluster e, portanto, ela demora muito mais tempo para carregar, atualizar ou inserir dados em várias tabelas. A distribuição ALL é apropriada somente para tabelas relativamente lentas; ou seja, tabelas que não são atualizadas frequentemente ou extensivamente. Como o custo de redistribuir tabelas pequenas durante uma consulta é baixo, não há um benefício significativo em definir tabelas de pequena dimensão como DISTSTYLE ALL. 

**nota**  
 Quando você tiver especificado um estilo de distribuição para uma coluna, o Amazon Redshift processa a distribuição em nível do cluster. O Amazon Redshift não exige ou é compatível com o conceito de particionamento de dados em objetos do banco de dados. Você não precisa criar espaços de tabela ou definir esquemas de particionamento para tabelas. 

Em alguns cenários, você pode alterar o estilo de distribuição de uma tabela depois de criada. Para obter mais informações, consulte [ALTER TABLE](r_ALTER_TABLE.md). Nos cenários em que não é possível mudar o estilo de distribuição de uma tabela depois da sua criação, você pode criar novamente a tabela e preenchê-la com uma cópia profunda. Para obter mais informações, consulte [Execução de uma cópia profunda](performing-a-deep-copy.md)

# Visualização dos estilos de distribuição
<a name="viewing-distribution-styles"></a>

Para exibir o estilo de distribuição de uma tabela, consulte a exibição PG\$1CLASS\$1INFO ou a exibição SVV\$1TABLE\$1INFO.

A coluna RELEFFECTIVEDISTSTYLE em PG\$1CLASS\$1INFO indica o estilo de distribuição atual da tabela. Se a tabela usar distribuição automática, RELEFFECTIVEDISTSTYLE será 10, 11 ou 12, o que indica se o estilo de distribuição efetivo é AUTO (ALL) ou AUTO (EVEN) ou AUTO (KEY). Se a tabela usar distribuição automática, o estilo de distribuição poderá mostrar inicialmente AUTO (ALL) e mudar para AUTO (EVEN) ou AUTO (KEY) quando a tabela crescer. 

A tabela a seguir fornece o estilo de distribuição para cada valor na coluna RELEFFECTIVEDISTSTYLE: 


| RELEFFECTIVEDISTSTYLE | Estilo de distribuição atual | 
| --- | --- | 
| 0 | EVEN | 
| 1 | KEY | 
| 8 | ALL | 
| 10 | AUTO (ALL) | 
| 11 | AUTO (EVEN) | 
| 12 | AUTO (KEY) | 

A coluna DISTSTYLE em SVV\$1TABLE\$1INFO indica o estilo de distribuição atual da tabela. Se a tabela usar distribuição automática, DISTSTYLE será AUTO (ALL) ou AUTO (EVEN) ou AUTO (KEY).

O exemplo a seguir cria quatro tabelas usando os três estilos de distribuição e distribuição automática e, em seguida, consulta SVV\$1TABLE\$1INFO para visualizar os estilos de distribuição. 

```
create table public.dist_key (col1 int)
diststyle key distkey (col1);

insert into public.dist_key values (1);

create table public.dist_even (col1 int)
diststyle even;

insert into public.dist_even values (1);

create table public.dist_all (col1 int)
diststyle all;

insert into public.dist_all values (1);

create table public.dist_auto (col1 int);

insert into public.dist_auto values (1);

select "schema", "table", diststyle from SVV_TABLE_INFO
where "table" like 'dist%';

        schema   |    table        | diststyle
     ------------+-----------------+------------
      public     | dist_key        | KEY(col1)
      public     | dist_even       | EVEN
      public     | dist_all        | ALL
      public     | dist_auto       | AUTO(ALL)
```

# Avaliação dos padrões de consulta
<a name="t_evaluating_query_patterns"></a>

 A escolha de estilos de distribuição é apenas um aspecto do design do banco de dados. Considere os estilos de distribuição somente no contexto do sistema completo, equilibrando a distribuição com outros fatores importantes, como o tamanho do cluster, os métodos de codificação de compactação, as chaves de classificação e as restrições da tabela. 

 Teste seu sistema com dados que sejam o mais próximo possível de dados reais. 

Para fazer boas escolhas para estilos de distribuição, você precisa entender os padrões de consulta para sua aplicação do Amazon Redshift. Identifique as consultas mais caras em seu sistema e baseie seu projeto inicial de banco de dados nas demandas dessas consultas. Os fatores que determinam o custo total de uma consulta incluem o tempo necessário para execução da consulta e a quantidade de recursos de computação consumida. Outros fatores que determinam o custo da consulta são a frequência de execução da consulta e o quanto ela interrompe outras consultas e operações do banco de dados. 

 Identifique as tabelas que são usadas pelas consultas mais caras e avalie seu perfil no runtime da consulta. Considere como as tabelas são associadas e agregadas. 

 Use as diretrizes nesta seção para escolher um estilo de distribuição para cada tabela. Depois de fazer isso, crie as tabelas e carregue-as com dados que sejam o mais próximo possível dos dados reais. Em seguida, teste as tabelas para os tipos de consultas que você espera usar. Você pode avaliar os planos de explicação da consulta para identificar oportunidades de ajuste. Compare os tempos de carregamento, o espaço de armazenamento e os runtimes da consulta para equilibrar os requisitos globais do seu sistema. 

# Designação de estilos de distribuição
<a name="t_designating_distribution_styles"></a>

 As considerações e recomendações para designação de estilos de distribuição neste seção usam um esquema estrela como exemplo. O design do seu banco de dados pode ser baseado em um esquema em estrela, alguma variante de um esquema em estrela ou um esquema totalmente diferente. O Amazon Redshift foi projetado para funcionar de maneira eficaz com qualquer projeto de esquema que você escolher. Os princípios nesta seção podem ser aplicados a qualquer esquema de design. 

1.  **Especifique a chave primária e chaves estrangeiras para todas as suas tabelas.** 

   O Amazon Redshift não impõe restrições de chave primária e chave estrangeira, mas o otimizador de consulta as usa ao gerar planos de consulta. Se você definir chaves primárias e chaves estrangeiras, seu aplicativo deverá manter a validade das chaves. 

1.  **Distribua a tabela de fatos e sua maior tabela de dimensões em suas colunas comuns.** 

   Escolha a maior dimensão com base no tamanho do conjunto de dados que participa da junção mais comum, não apenas no tamanho da tabela. Se uma tabela é geralmente filtrada usando uma cláusula WHERE, somente uma porção de suas linhas participam da junção. Tal tabela tem menor impacto na redistribuição do que uma tabela menor que contribua mais dados. Designe a chave primária da tabela de dimensões e a chave estrangeira correspondente da tabela de fatos como DISTKEY. Se várias tabelas usarem a mesma chave de distribuição, elas também serão colocadas com a tabela de fatos. Sua tabela de fatos pode ter apenas uma chave de distribuição. Quaisquer tabelas que se juntam em outra chave não são colocadas com a tabela de fatos. 

1.  **Designe as chaves de distribuição para as outras tabelas de dimensões.** 

   Distribua as tabelas em suas chaves primárias ou em suas chaves estrangeiras, dependendo de como elas geralmente se juntam com outras tabelas. 

1.  **Avalie a necessidade de alterar algumas das tabelas de dimensões para usar a distribuição ALL.** 

   Se uma tabela de dimensão não pode ser disposta com a tabela de fato ou outras tabelas de junção importantes, você pode melhorar a performance da consulta significativamente ao distribuir toda a tabela para todos os nós. O uso de distribuição ALL multiplica as exigências de espaço de armazenamento e aumenta os tempos de carregamento e operações de manutenção, portanto você deve considerar todos os fatores antes de optar pela distribuição ALL. A seção a seguir explica como identificar candidatos para a distribuição ALL ao avaliar o plano EXPLAIN. 

1.  **Use a distribuição AUTO para as tabelas restantes.** 

   Se uma tabela for amplamente desnormalizada e não participar de junções, ou se você não tiver uma opção clara de outro estilo de distribuição, use a distribuição AUTO. 

Para permitir que o Amazon Redshift escolha o estilo de distribuição apropriado, não especifique explicitamente um estilo de distribuição.

# Avaliação do plano de consulta
<a name="c_data_redistribution"></a>

Você pode usar planos de consulta para identificar candidatos para otimização do estilo de distribuição. 

Após tomar as decisões iniciais de design, crie suas tabelas, preencha-as com dados e teste-as. Use um conjunto de dados de teste que seja o mais próximo possível dos dados reais. Meça o tempo de carregamento para usar como linha de base para comparações. 

Avalie as consultas que representam as consultas mais caras que você espera executar, especificamente as consultas que usam junções e agregações. Compare os runtimes para várias opções de design. Ao comparar runtimes, não conte a primeira vez que a consulta é executada, porque o primeiro runtime inclui o tempo de compilação. 

**DS\$1DIST\$1NONE**  
Nenhuma redistribuição é necessária, pois as fatias correspondentes são arranjadas nos nós de computação. Normalmente, você tem apenas uma etapa DS\$1DIST\$1NONE, a junção entre a tabela de fatos e uma tabela de dimensão. 

**DS\$1DIST\$1ALL\$1NONE**  
Nenhuma redistribuição é necessária, pois a tabela de junção interna usou DISTSTYLE ALL. A tabela completa está localizada em todos os nós. 

**DS\$1DIST\$1INNER**  
A tabela interna é redistribuída. 

**DS\$1DIST\$1OUTER**  
A tabela externa é redistribuída. 

**DS\$1BCAST\$1INNER**  
Uma cópia de toda a tabela interna é transmitida a todos os nós de computação. 

**DS\$1DIST\$1ALL\$1INNER**  
Toda a tabela interna é redistribuída a uma única fatia, pois a tabela externa usa DISTSTYLE ALL.

**DS\$1DIST\$1BOTH**  
Ambas as tabelas são redistribuídas. 

**DS\$1DIST\$1ERR**  
Quando a tabela não tem um estilo de distribuição selecionado.

DS\$1DIST\$1NONE e DS\$1DIST\$1ALL\$1NONE são bons. Eles indicam que nenhuma distribuição foi necessária para esta etapa, pois todas as junções estão dispostas. 

DS\$1DIST\$1INNER significa que a etapa provavelmente tem um custo relativamente alto porque a tabela interna está sendo redistribuída para os nós. DS\$1DIST\$1INNER indica que a tabela externa já está adequadamente distribuída na chave de junção. Defina a chave de distribuição da tabela interna como a chave de junção para converter isso para DS\$1DIST\$1NONE. Em alguns casos, a distribuição da tabela interna na chave de junção não é possível porque a tabela externa não está distribuída na chave de junção. Se esse for o caso, avalie se deseja usar a distribuição ALL para a tabela interna. Se a tabela não for atualizada com frequência ou extensivamente e for grande o suficiente para suportar um alto custo de redistribuição, altere o estilo de distribuição para ALL e teste novamente. A distribuição ALL resulta em maior tempos de carregamento, portanto ao testar novamente, inclua o tempo de carregamento em seus fatores de avaliação. 

DS\$1DIST\$1ALL\$1INNER não é bom. Isso significa que toda a tabela interna é redistribuída em uma única fatia, pois a tabela externa usa DISTSTYLE ALL, de forma que uma cópia de toda a tabela externa está localizada em cada nó. Isso resulta em runtime em série ineficaz da junção em um único nó, em vez de tirar proveito do runtime paralelo usando todos os nós. DISTSTYLE ALL é destinado ao uso somente para a tabela de junção interna. Em vez disso, especifique uma chave de distribuição ou use a distribuição uniforme para a tabela externa.

DS\$1BCAST\$1INNER e DS\$1DIST\$1BOTH não são bons. Geralmente, essas redistribuições ocorrem pois as tabelas não são associadas em suas chaves de distribuição. Se a tabela de fatos ainda não tiver uma chave de distribuição, especifique a coluna de junção como a chave de distribuição para ambas as tabelas. Se a tabela de fatos já tiver uma chave de distribuição em outra coluna, avalie se alterar a chave de distribuição para colocar essa junção melhora a performance geral. Se alterar a chave de distribuição da tabela externa não for uma escolha ideal, você pode obter a colocação especificando DISTSTYLE ALL para a tabela interna. 

 O seguinte exemplo mostra uma porção de um plano de consulta com os rótulos DS\$1BCAST\$1INNER e DS\$1DIST\$1NONE.

```
->  XN Hash Join DS_BCAST_INNER  (cost=112.50..3272334142.59 rows=170771 width=84)
        Hash Cond: ("outer".venueid = "inner".venueid)
        ->  XN Hash Join DS_BCAST_INNER  (cost=109.98..3167290276.71 rows=172456 width=47)
              Hash Cond: ("outer".eventid = "inner".eventid)
              ->  XN Merge Join DS_DIST_NONE  (cost=0.00..6286.47 rows=172456 width=30)
                    Merge Cond: ("outer".listid = "inner".listid)
                    ->  XN Seq Scan on listing  (cost=0.00..1924.97 rows=192497 width=14)
                    ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=24)
```

Após a alteração das tabelas de dimensões para uso de DISTSTYLE ALL, o plano de consulta para a mesma consulta exibe DS\$1DIST\$1ALL\$1NONE em vez de DS\$1BCAST\$1INNER. Além disso, há uma alteração drástica no custo relativo para as etapas da junção. O custo total é `14142.59` comparado ao `3272334142.59` da consulta anterior.

```
->  XN Hash Join DS_DIST_ALL_NONE  (cost=112.50..14142.59 rows=170771 width=84)
        Hash Cond: ("outer".venueid = "inner".venueid)
        ->  XN Hash Join DS_DIST_ALL_NONE  (cost=109.98..10276.71 rows=172456 width=47)
              Hash Cond: ("outer".eventid = "inner".eventid)
              ->  XN Merge Join DS_DIST_NONE  (cost=0.00..6286.47 rows=172456 width=30)
                    Merge Cond: ("outer".listid = "inner".listid)
                    ->  XN Seq Scan on listing  (cost=0.00..1924.97 rows=192497 width=14)
                    ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=24)
```

# Exemplo de plano de consulta
<a name="t_explain_plan_example"></a>

Este exemplo mostra como avaliar um plano de consulta para encontrar oportunidades de otimização da distribuição.

Execute a seguinte consulta com um comando EXPLAIN para produzir um plano de consulta.

```
explain
select lastname, catname, venuename, venuecity, venuestate, eventname, 
month, sum(pricepaid) as buyercost, max(totalprice) as maxtotalprice
from category join event on category.catid = event.catid
join venue on venue.venueid = event.venueid
join sales on sales.eventid = event.eventid
join listing on sales.listid = listing.listid
join date on sales.dateid = date.dateid
join users on users.userid = sales.buyerid
group by lastname, catname, venuename, venuecity, venuestate, eventname, month
having sum(pricepaid)>9999
order by catname, buyercost desc;
```

No banco de dados TICKIT, SALES é uma tabela de fatos e LISTING é a maior dimensão. Para posicionar as tabelas, SALES é distribuída em LISTID, que é a chave estrangeira para LISTING, e LISTING é distribuída em sua chave primária, LISTID. O exemplo a seguir mostra os comandos CREATE TABLE para SALES e LISTING.

```
create table sales(
	salesid integer not null,
	listid integer not null distkey,
	sellerid integer not null,
	buyerid integer not null,
	eventid integer not null encode mostly16,
	dateid smallint not null,
	qtysold smallint not null encode mostly8,
	pricepaid decimal(8,2) encode delta32k,
	commission decimal(8,2) encode delta32k,
	saletime timestamp,
	primary key(salesid),
	foreign key(listid) references listing(listid),
	foreign key(sellerid) references users(userid),
	foreign key(buyerid) references users(userid),
	foreign key(dateid) references date(dateid))
        sortkey(listid,sellerid);

create table listing(
	listid integer not null distkey sortkey,
	sellerid integer not null,
	eventid integer not null encode mostly16,
	dateid smallint not null,
	numtickets smallint not null encode mostly8,
	priceperticket decimal(8,2) encode bytedict,
	totalprice decimal(8,2) encode mostly32,
	listtime timestamp,
	primary key(listid),
	foreign key(sellerid) references users(userid),
	foreign key(eventid) references event(eventid),
	foreign key(dateid) references date(dateid));
```

No seguinte plano de consulta, a etapa merge join para a junção em SALES e LISTING mostra DS\$1DIST\$1NONE, que indica que nenhuma redistribuição é necessária para a etapa. No entanto, mais acima no plano de consulta, outras junções internas exibem DS\$1BCAST\$1INNER, que indica que a tabela interna é transmitida como parte da execução da consulta. Como somente um par de tabelas pode ser posicionado usando a distribuição de chaves, cinco tabelas precisam ser retransmitidas.

```
QUERY PLAN
XN Merge  (cost=1015345167117.54..1015345167544.46 rows=1000 width=103)
  Merge Key: category.catname, sum(sales.pricepaid)
  ->  XN Network  (cost=1015345167117.54..1015345167544.46 rows=170771 width=103)
        Send to leader
        ->  XN Sort  (cost=1015345167117.54..1015345167544.46 rows=170771 width=103)
              Sort Key: category.catname, sum(sales.pricepaid)
              ->  XN HashAggregate  (cost=15345150568.37..15345152276.08 rows=170771 width=103)
                    Filter: (sum(pricepaid) > 9999.00)
	                    ->  XN Hash Join DS_BCAST_INNER  (cost=742.08..15345146299.10 rows=170771 width=103)
	                          Hash Cond: ("outer".catid = "inner".catid)
	                          ->  XN Hash Join DS_BCAST_INNER  (cost=741.94..15342942456.61 rows=170771 width=97)
	                                Hash Cond: ("outer".dateid = "inner".dateid)
	                                ->  XN Hash Join DS_BCAST_INNER  (cost=737.38..15269938609.81 rows=170766 width=90)
	                                      Hash Cond: ("outer".buyerid = "inner".userid)
	                                      ->  XN Hash Join DS_BCAST_INNER  (cost=112.50..3272334142.59 rows=170771 width=84)
	                                            Hash Cond: ("outer".venueid = "inner".venueid)
	                                            ->  XN Hash Join DS_BCAST_INNER  (cost=109.98..3167290276.71 rows=172456 width=47)
	                                                  Hash Cond: ("outer".eventid = "inner".eventid)
	                                                  ->  XN Merge Join DS_DIST_NONE  (cost=0.00..6286.47 rows=172456 width=30)
	                                                        Merge Cond: ("outer".listid = "inner".listid)
	                                                        ->  XN Seq Scan on listing  (cost=0.00..1924.97 rows=192497 width=14)
	                                                        ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=24)
	                                                  ->  XN Hash  (cost=87.98..87.98 rows=8798 width=25)
	                                                        ->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=25)
	                                            ->  XN Hash  (cost=2.02..2.02 rows=202 width=41)
	                                                  ->  XN Seq Scan on venue  (cost=0.00..2.02 rows=202 width=41)
	                                      ->  XN Hash  (cost=499.90..499.90 rows=49990 width=14)
	                                            ->  XN Seq Scan on users  (cost=0.00..499.90 rows=49990 width=14)
	                                ->  XN Hash  (cost=3.65..3.65 rows=365 width=11)
	                                      ->  XN Seq Scan on date  (cost=0.00..3.65 rows=365 width=11)
	                          ->  XN Hash  (cost=0.11..0.11 rows=11 width=10)
	                                ->  XN Seq Scan on category  (cost=0.00..0.11 rows=11 width=10)
```

Uma solução é alterar as tabelas para que tenham DISTSTYLE ALL.

```
ALTER TABLE users ALTER DISTSTYLE ALL;
ALTER TABLE venue ALTER DISTSTYLE ALL;
ALTER TABLE category ALTER DISTSTYLE ALL;
ALTER TABLE date ALTER DISTSTYLE ALL;
ALTER TABLE event ALTER DISTSTYLE ALL;
```

Execute a mesma consulta com EXPLAIN novamente e examine o novo plano de consulta. As junções agora exibem DS\$1DIST\$1ALL\$1NONE, indicando que nenhuma redistribuição é necessária, pois os dados foram distribuídos para todos os nós usando DISTSTYLE ALL.

```
QUERY PLAN
XN Merge  (cost=1000000047117.54..1000000047544.46 rows=1000 width=103)
  Merge Key: category.catname, sum(sales.pricepaid)
  ->  XN Network  (cost=1000000047117.54..1000000047544.46 rows=170771 width=103)
        Send to leader
        ->  XN Sort  (cost=1000000047117.54..1000000047544.46 rows=170771 width=103)
              Sort Key: category.catname, sum(sales.pricepaid)
              ->  XN HashAggregate  (cost=30568.37..32276.08 rows=170771 width=103)
                    Filter: (sum(pricepaid) > 9999.00)
                    ->  XN Hash Join DS_DIST_ALL_NONE  (cost=742.08..26299.10 rows=170771 width=103)
                          Hash Cond: ("outer".buyerid = "inner".userid)
                          ->  XN Hash Join DS_DIST_ALL_NONE  (cost=117.20..21831.99 rows=170766 width=97)
                                Hash Cond: ("outer".dateid = "inner".dateid)
                                ->  XN Hash Join DS_DIST_ALL_NONE  (cost=112.64..17985.08 rows=170771 width=90)
                                      Hash Cond: ("outer".catid = "inner".catid)
                                      ->  XN Hash Join DS_DIST_ALL_NONE  (cost=112.50..14142.59 rows=170771 width=84)
                                            Hash Cond: ("outer".venueid = "inner".venueid)
                                            ->  XN Hash Join DS_DIST_ALL_NONE  (cost=109.98..10276.71 rows=172456 width=47)
                                                  Hash Cond: ("outer".eventid = "inner".eventid)
                                                  ->  XN Merge Join DS_DIST_NONE  (cost=0.00..6286.47 rows=172456 width=30)
                                                        Merge Cond: ("outer".listid = "inner".listid)
                                                        ->  XN Seq Scan on listing  (cost=0.00..1924.97 rows=192497 width=14)
                                                        ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=24)
                                                  ->  XN Hash  (cost=87.98..87.98 rows=8798 width=25)
                                                        ->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=25)
                                            ->  XN Hash  (cost=2.02..2.02 rows=202 width=41)
                                                  ->  XN Seq Scan on venue  (cost=0.00..2.02 rows=202 width=41)
                                      ->  XN Hash  (cost=0.11..0.11 rows=11 width=10)
                                            ->  XN Seq Scan on category  (cost=0.00..0.11 rows=11 width=10)
                                ->  XN Hash  (cost=3.65..3.65 rows=365 width=11)
                                      ->  XN Seq Scan on date  (cost=0.00..3.65 rows=365 width=11)
                          ->  XN Hash  (cost=499.90..499.90 rows=49990 width=14)
                                ->  XN Seq Scan on users  (cost=0.00..499.90 rows=49990 width=14)
```

# Exemplos de distribuição
<a name="c_Distribution_examples"></a>

Os seguintes exemplos mostram como os dados são distribuídos de acordo com as opções que você define na instrução CREATE TABLE.

## Exemplos de DISTKEY
<a name="c_Distribution_examples-distkey-examples"></a>

Observe o esquema da tabela USERS no banco de dados TICKIT. USERID é definida como a coluna SORTKEY e a coluna DISTKEY: 

```
select "column", type, encoding, distkey, sortkey 
from pg_table_def where tablename = 'users';
    
    column     |          type          | encoding | distkey | sortkey
---------------+------------------------+----------+---------+---------
 userid        | integer                | none     | t       |       1
 username      | character(8)           | none     | f       |       0
 firstname     | character varying(30)  | text32k  | f       |       0

...
```

USERID é uma boa escolha para a coluna de distribuição dessa tabela. Se você consultar a exibição de sistema SVV\$1DISKUSAGE, verá que a tabela é distribuída de forma bastante uniforme. Os números de coluna são baseados em zero, portanto USERID é a coluna 0.

```
select slice, col, num_values as rows, minvalue, maxvalue
from svv_diskusage
where name='users' and col=0 and rows>0
order by slice, col;

slice| col | rows  | minvalue | maxvalue
-----+-----+-------+----------+----------
0    | 0   | 12496 | 4        | 49987
1    | 0   | 12498 | 1        | 49988
2    | 0   | 12497 | 2        | 49989
3    | 0   | 12499 | 3        | 49990
(4 rows)
```

A tabela contém 49.990 linhas. As coluna de linhas (num\$1values) mostra que cada fatia contém aproximadamente o mesmo número de linhas. As colunas minvalue e maxvalue exibem o intervalo de valores em cada fatia. Cada fatia inclui quase todo o intervalo de valores, portanto, há uma boa chance de que cada fatia participe da execução de uma consulta que filtra uma variedade de IDs de usuário.

Este exemplo demonstra a distribuição em um pequeno sistema de teste. O número total de fatias é geralmente muito maior.

Se você normalmente realiza junções ou agrupamentos usando a coluna STATE, pode optar por distribuir na coluna STATE. O exemplo a seguir mostra um caso em que você cria uma nova tabela com os mesmos dados da tabela USERS, mas define DISTKEY para a coluna STATE. Neste caso, a distribuição não é igual. A fatia 0 (13.587 linhas) contém aproximadamente 30 por cento mais linhas do que a fatia 3 (10.150 linhas). Em uma tabela muito maior, essa quantidade de distorção de distribuição pode ter um impacto adverso no processamento de consultas.

```
create table userskey distkey(state) as select * from users;

select slice, col, num_values as rows, minvalue, maxvalue from svv_diskusage
where name = 'userskey' and col=0 and rows>0
order by slice, col;

slice | col | rows  | minvalue | maxvalue
------+-----+-------+----------+----------
    0 |   0 | 13587 |        5 |    49989
    1 |   0 | 11245 |        2 |    49990
    2 |   0 | 15008 |        1 |    49976
    3 |   0 | 10150 |        4 |    49986
(4 rows)
```

## Exemplo de DISTSTYLE EVEN
<a name="c_Distribution_examples-diststyle-even-example"></a>

Se você criar uma nova tabela com os mesmos dados da tabela USERS, mas definir DISTSTYLE como EVEN, as linhas sempre serão distribuídas uniformemente ao longo das fatias. 

```
create table userseven diststyle even as 
select * from users;

select slice, col, num_values as rows, minvalue, maxvalue from svv_diskusage
where name = 'userseven' and col=0 and rows>0
order by slice, col;

slice | col | rows  | minvalue | maxvalue
------+-----+-------+----------+----------
    0 |   0 | 12497 |        4 |    49990
    1 |   0 | 12498 |        8 |    49984
    2 |   0 | 12498 |        2 |    49988
    3 |   0 | 12497 |        1 |    49989  
(4 rows)
```

Entretanto, como a distribuição não é baseada em uma coluna específica, o processamento da consulta pode ser degradado, especialmente se a tabela estiver associada à outras tabelas. A falta de distribuição em uma coluna de junção frequentemente influencia o tipo de operação de junção que pode ser executada eficientemente. Operações de junção, agregação e agrupamento são otimizadas quando ambas as tabelas são distribuídas e classificadas em suas respectivas colunas de junção.

## Exemplo de DISTSTYLE ALL
<a name="c_Distribution_examples-diststyle-all-example"></a>

Se você criar uma nova tabela com os mesmos dados da tabela USERS, mas definir DISTSTYLE como ALL, todas as linhas serão distribuídas para a primeira fatia de cada nó. 

```
select slice, col, num_values as rows, minvalue, maxvalue from svv_diskusage
where name = 'usersall' and col=0 and rows > 0
order by slice, col;

slice | col | rows  | minvalue | maxvalue
------+-----+-------+----------+----------
    0 |   0 | 49990 |        4 |    49990
    2 |   0 | 49990 |        2 |    49990

(4 rows)
```