

 Amazon Redshift non supporterà più la creazione di nuovi Python UDFs a partire dalla Patch 198. Python esistente UDFs continuerà a funzionare fino al 30 giugno 2026. Per ulteriori informazioni, consulta il [post del blog](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Distribuzione dei dati per l’ottimizzazione delle query
<a name="t_Distributing_data"></a>

Quando si caricano i dati in una tabella, Amazon Redshift distribuisce le righe della tabella su tutti i nodi di calcolo a seconda dello stile di distribuzione della tabella. Quando si esegue una query, l'ottimizzatore di query ridistribuisce le righe sui nodi di calcolo per eseguire qualsiasi operazione di join e aggregazione, in base alle necessità. La selezione di uno stile di distribuzione di tabella ha l'obiettivo di ridurre al minimo l'impatto della fase di ridistribuzione posizionando i dati dove necessario prima dell'esecuzione della query.

**Nota**  
In questa sezione verranno presentati i principi della distribuzione dei dati in un database Amazon Redshift. È consigliabile creare le tabelle con `DISTSTYLE AUTO`. In tal caso, Amazon Redshift utilizza l'ottimizzazione automatica della tabella per scegliere lo stile di distribuzione dei dati. Per ulteriori informazioni, consultare [Ottimizzazione automatica delle tabelle](t_Creating_tables.md). Il resto di questa sezione fornisce dettagli sugli stili di distribuzione. 

**Topics**
+ [Concetti della distribuzione dei dati](#t_data_distribution_concepts)
+ [Stili di distribuzione](c_choosing_dist_sort.md)
+ [Visualizzazione degli stili di distribuzione](viewing-distribution-styles.md)
+ [Valutazione dei modelli di query](t_evaluating_query_patterns.md)
+ [Indicazione degli stili di distribuzione](t_designating_distribution_styles.md)
+ [Valutazione del piano di query](c_data_redistribution.md)
+ [Esempio del piano di query](t_explain_plan_example.md)
+ [Esempi di distribuzione](c_Distribution_examples.md)

## Concetti della distribuzione dei dati
<a name="t_data_distribution_concepts"></a>

Di seguito sono riportati alcuni concetti di distribuzione dei dati per Amazon Redshift.

 **Nodi e sezioni** 

 Un cluster Amazon Redshift è un set di nodi. Ogni nodo nel cluster ha il proprio sistema operativo, una memoria dedicata e uno storage del disco dedicato. Uno dei nodi è il *nodo principale*, il quale gestisce la distribuzione dei dati ed esegue query delle attività di elaborazione ai nodi di calcolo. I *nodi di calcolo* forniscono risorse per eseguire tali attività. 

 Lo storage del disco di un nodo di calcolo è diviso in un numero di *sezioni*. Il numero di sezioni per nodo dipende dalla dimensione dei nodi del cluster. Tutti i nodi partecipano all'esecuzione di query parallele, lavorando sui dati di calcolo distribuiti più uniformemente possibile all'interno delle sezioni. Per ulteriori informazioni sul numero di sezioni per ogni dimensione di nodo, consulta [Informazioni su cluster e nodi](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#rs-about-clusters-and-nodes) nella *Guida alla gestione di Amazon Redshift*.

 **Ridistribuzione dei dati** 

 Quando si caricano i dati in una tabella, Amazon Redshift distribuisce le righe della tabella su ognuna delle sezioni dei nodi a seconda dello stile di distribuzione della tabella. Come parte di un piano di query, l'ottimizzatore determina dove è necessario posizionare i blocchi dei dati per la migliore esecuzione della query. I dati quindi vengono spostati fisicamente, o ridistribuiti, durante l'esecuzione della query. La redistribuzione potrebbe comportare l'invio di specifiche righe ai nodi per il join o la diffusione di un'intera tabella a tutti i nodi. 

 La ridistribuzione dei dati può contare su una porzione sostanziale dei costi del piano di query; inoltre, il traffico di rete generato dalla ridistribuzione dei dati, può influire sulle altre operazioni del database e può rallentare le prestazioni generali del sistema. Qualora prevedessi dove converrebbe posizionare inizialmente i dati, potrai minimizzare l'impatto della ridistribuzione dei dati. 

 **Obiettivi della distribuzione dei dati** 

 Quando si caricano i dati in una tabella, Amazon Redshift distribuisce le righe della tabella su tutti i nodi di calcolo e alle sezioni, a seconda dello stile di distribuzione scelto al momento della creazione della tabella. La distribuzione dei dati ha due obiettivi principali: 
+ Distribuire il carico di lavoro uniformemente su tutti i nodi del cluster. La distribuzione di dati non uniforme, o la differenza di distribuzione dei dati, forza alcuni nodi a lavorare maggiormente rispetto ad altri e compromette le prestazioni della query.
+ Minimizzare lo spostamento dei dati durante l'esecuzione di una query. Se le righe che partecipano a join o alle aggregazioni si trovano già sui nodi con le loro righe di join in altre tabelle, l'ottimizzatore non dovrà ridistribuire molti dati durante l'esecuzione della query.

La strategia di distribuzione che hai scelto per il tuo database avrà importanti ripercussioni sulle prestazioni della query, sui requisiti dello storage, sul caricamento dei dati e sulla manutenzione. Scegliendo lo stile di distribuzione migliore per ogni tabella, puoi bilanciare la distribuzione dei dati e migliorare in modo significativo le prestazioni generali del sistema.

# Stili di distribuzione
<a name="c_choosing_dist_sort"></a>

Quando crei una tabella, puoi indicare uno dei seguenti stili di distribuzione: AUTO, EVEN, KEY o ALL. 

Se non si specifica uno stile di distribuzione, Amazon Redshift utilizza la distribuzione AUTO.

 **Distribuzione AUTO** 

Con la distribuzione AUTO, Amazon Redshift assegna uno stile di distribuzione ottimale basato sulla dimensione dei dati della tabella. Ad esempio, se viene specificato lo stile di distribuzione AUTO, Amazon Redshift assegna inizialmente la distribuzione ALL a una tabella di piccole dimensioni. Quando le dimensioni della tabella aumentano, Amazon Redshift potrebbe modificare lo stile di distribuzione in KEY, scegliendo la chiave primaria (o una colonna della chiave primaria composita) come chiave di distribuzione. Se le dimensioni della tabella aumentano e nessuna delle colonne è adatta per essere utilizzata come chiave di distribuzione, Amazon Redshift modifica lo stile di distribuzione in EVEN. La modifica dello stile di distribuzione avviene in background con un impatto minimo sulle query degli utenti. 

Per visualizzare le operazioni eseguite automaticamente da Amazon Redshift per modificare una chiave di distribuzione della tabella, consultare [SVL\$1AUTO\$1WORKER\$1ACTION](r_SVL_AUTO_WORKER_ACTION.md). Per visualizzare i suggerimenti correnti relativi alla modifica di una chiave di distribuzione della tabella, consultare [SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS](r_SVV_ALTER_TABLE_RECOMMENDATIONS.md). 

Per visualizzare lo stile di distribuzione applicato a una tabella, eseguire una query sulla visualizzazione del catalogo di sistema PG\$1CLASS\$1INFO. Per ulteriori informazioni, consultare [Visualizzazione degli stili di distribuzione](viewing-distribution-styles.md). Se non si specifica uno stile di distribuzione con l'istruzione CREATE TABLE, Amazon Redshift applica la distribuzione AUTO. 

 **Distribuzione EVEN** 

 Il nodo principale distribuisce le righe tra le sezioni con un metodo round robin, indipendentemente dai valori in una determinata colonna. La distribuzione EVEN è appropriata quando una tabella non partecipa ai join. È appropriata anche quando non c'è una scelta chiara tra la distribuzione KEY e la distribuzione ALL.

 **Distribuzione KEY** 

 Le righe sono distribuite in funzione dei valori in una colonna. Il nodo principale posiziona valori corrispondenti sulla stessa sezione di nodo. Se si distribuisce una coppia di tabelle sulle chiavi di join, il nodo principale colloca le righe sulle sezioni in funzione dei valori nelle colonne di join affinché i valori corrispondenti delle colonne comuni siano archiviati fisicamente insieme. In questo modo, i valori corrispondenti delle colonne comuni vengono fisicamente memorizzati insieme. 

 **Distribuzione ALL** 

 Un copia dell'intera tabella viene distribuita a ogni nodo. Dove la distribuzione EVEN o KEY posiziona solo una parte delle righe di una tabella su ogni nodo, la distribuzione ALL assicura la collocazione di ogni riga per ogni join a cui la tabella partecipa. 

 La distribuzione ALL moltiplica lo storage richiesto dal numero di nodi nel cluster, quindi impiega più tempo per caricare, aggiornare o inserire i dati in più tabelle. La distribuzione ALL è idonea solo per spostamenti relativamente lenti delle tabelle, ovvero per le tabelle che non vengono aggiornate intensamente o frequentemente. Poiché il costo della ridistribuzione di piccole tabelle durante una query è basso, non vi è un vantaggio significativo per definire le tabelle di dimensioni ridotte come DISTSTYLE ALL. 

**Nota**  
 Dopo aver specificato uno stile di distribuzione per una colonna, Amazon Redshift gestisce la distribuzione dei dati a livello di cluster. Amazon Redshift non richiede né supporta il concetto di partizionamento dei dati all'interno degli oggetti del database. Non è necessario creare spazi di tabelle o definire schemi di partizionamento per le tabelle. 

In alcuni scenari, puoi modificare lo stile di distribuzione di una tabella dopo che è stata creata. Per ulteriori informazioni, consultare [ALTER TABLE](r_ALTER_TABLE.md). Per gli scenari in cui non puoi modificare lo stile di distribuzione di una tabella dopo che è stata creata, puoi ricreare la tabella e popolarla con una copia completa. Per ulteriori informazioni, consultare [Esecuzione di una copia completa](performing-a-deep-copy.md)

# Visualizzazione degli stili di distribuzione
<a name="viewing-distribution-styles"></a>

Per visualizzare lo stile di distribuzione di una tabella, eseguire una query sulla visualizzazione PG\$1CLASS\$1INFO o SVV\$1TABLE\$1INFO.

La colonna RELEFFECTIVEDISTSTYLE in PG\$1CLASS\$1INFO indica lo stile di distribuzione attuale per la tabella. Se la tabella utilizza la distribuzione automatica, RELEFFECTIVEDISTSTYLE è 10, 11 o 12 che indica se lo stile di distribuzione effettivo è AUTO (ALL), AUTO (EVEN) o AUTO (KEY). Se la tabella utilizza la distribuzione automatica, lo stile di distribuzione potrebbe inizialmente mostrare AUTO (ALL), quindi passare ad AUTO (EVEN) o AUTO (KEY) quando le dimensioni della tabella aumentano. 

La seguente tabella fornisce lo stile di distribuzione per ogni valore su RELEFFECTIVEDISTSTYLE: 


| RELEFFECTIVEDISTSTYLE | Stile di distribuzione attuale | 
| --- | --- | 
| 0 | EVEN | 
| 1 | KEY | 
| 8 | ALL | 
| 10 | AUTO (ALL) | 
| 11 | AUTO (EVEN) | 
| 12 | AUTO (KEY) | 

La colonna DISTSTYLE in SVV\$1TABLE\$1INFO indica lo stile di distribuzione attuale per la tabella. Se la tabella utilizza la distribuzione automatica, DISTSTYLE è AUTO (ALL), AUTO (EVEN) o AUTO (KEY).

L'esempio seguente crea quattro tabelle mediante l'uso di tre stili di distribuzione e distribuzione automatica, quindi esegue una query SVV\$1TABLE\$1INFO per visualizzare gli stili di distribuzione. 

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

# Valutazione dei modelli di query
<a name="t_evaluating_query_patterns"></a>

 La scelta di stili di distribuzione è solo uno degli aspetti della progettazione del database. Si dovrebbero prendere in considerazione gli stili di distribuzione solo all'interno del contesto dell'intero sistema, bilanciando la distribuzione con altri importanti fattori, come la dimensione dei cluster, i metodi di codifica della compressione, le chiavi di ordinamento e i limiti della tabella. 

 Esegui dei test sul tuo sistema con dei dati che siano più reali possibili. 

Per scegliere lo stile di distribuzione migliore, sarà necessario capire i modelli di query per l'applicazione Amazon Redshift. Identifica le query più costose nel tuo sistema e basa il progetto iniziale del database sulle richieste di queste query. I fattori che determinano il costo totale di una query sono i tempi di esecuzione della query e i relativi consumi di risorse di calcolo. Altri fattori che determinano il costo della query sono i tempi di esecuzione e quanto le altre query e le operazioni del database vengono rivoluzionate. 

 Identificare le tabelle utilizzate dalle query più costose e valutare il loro ruolo nel runtime delle query. Considera il modo in cui le tabelle vengono combinate e aggregate. 

 Utilizza le linee guida di questa sezione per scegliere uno stile di distribuzione per ogni tabella. Dopo averlo fatto, creare le tabelle e caricarle con dei dati che siano più reali possibile. Quindi testare le tabelle per i tipi di query che si prevede di utilizzare. Puoi valutare i piani di illustrazione di query per identificare le opportunità di ottimizzazione. Confrontare i tempi di caricamento, lo spazio di archiviazione e i tempi di esecuzione della query per bilanciare i requisiti generali del sistema. 

# Indicazione degli stili di distribuzione
<a name="t_designating_distribution_styles"></a>

 In questa sezione, le considerazioni e le raccomandazioni per l'indicazione degli stili di distribuzione utilizzano uno schema a stella come esempio. Il progetto del database potrebbe essere basato su uno star schema, su alcune sue varianti o su uno schema completamente diverso. Amazon Redshift è progettato per funzionare in modo efficace con qualsiasi schema di progettazione scelto. I principi di questa sezione possono essere applicati a qualsiasi schema di progetto. 

1.  **Specificare la chiave primaria e le chiavi esterne per tutte le tabelle.** 

   Amazon Redshift non applica limitazioni di chiavi primarie o esterne, ma l'ottimizzatore di query le utilizza quando genera i piani di query. Se imposti le chiavi primarie e quelle esterne, la tua applicazione dovrà mantenere la validità delle chiavi. 

1.  **Distribuire le tabelle dei fatti e le sue tabelle di dimensioni più grandi sulle loro colonne comuni.** 

   Scegli quella di dimensioni più grandi a seconda della dimensione del set di dati coinvolto nel join più comune, non solo per la dimensione della tabella. Se una tabella di solito viene filtrata mediante l'utilizzo della clausola WHERE, solo una parte delle sue righe parteciperà alla combinazione. Tabelle del genere hanno un impatto minore sulla ridistribuzione rispetto a tabelle più piccole che forniscono più dati. Indica sia la dimensione della chiave primaria della tabella che la chiave esterna corrispondente della tabella dei fatti come DISTKEY. Se più tabelle utilizzano la stessa chiave di distribuzione, verranno posizionate con la tabella dei fatti. La tabella dei fatti può avere una sola chiave di distribuzione. Le tabelle che eseguono l'operazione join su un'altra chiave non sono collocate con la tabella dei fatti. 

1.  **Indicare le chiavi di distribuzione per le altre tabelle dimensionali.** 

   Distribuisci le tabelle sulle loro chiavi primarie o esterne, a seconda di come combinano più frequentemente con le altre tabelle. 

1.  **Valutare se sia il caso di modificare alcune tabelle dimensionali per utilizzare la dimensione ALL.** 

   Se una tabella di dimensioni non può essere collocata con la tabella dei fatti o altre importanti tabelle di join, è spesso possibile migliorare le prestazioni delle query in modo significativo distribuendo l'intera tabella su tutti i nodi. L'utilizzo della distribuzione ALL moltiplica i requisiti di spazio di storage e aumenta i tempi di caricamento oltre che le operazioni di manutenzione; è quindi necessario valutare tutti i fattori prima di scegliere la distribuzione ALL. La seguente sezione illustra come identificare i candidati per la distribuzione ALL, mediante la valutazione del piano EXPLAIN. 

1.  **Utilizzare la distribuzione AUTO per le tabelle restanti.** 

   Se una tabella è ampiamente denormalizzata e non partecipa ai join, oppure se non hai ben chiara la scelta di un altro stile di distribuzione, utilizza la distribuzione AUTO. 

Per permettere ad Amazon Redshift di scegliere lo stile di distribuzione appropriato, non specificare esplicitamente una distribuzione automatica.

# Valutazione del piano di query
<a name="c_data_redistribution"></a>

Puoi utilizzare i piani di query per identificare i candidati per l'ottimizzazione dello stile di distribuzione. 

Dopo avere fatto la scelta iniziale, crea le tue tabelle, caricale con i dati e verificale. Utilizza un set di dati per il test che sia più reale possibile. Misura i tempi di caricamento per utilizzarli come riferimento per il confronto. 

Valutare le query che sono rappresentative di quelle più costose che verranno eseguite; nello specifico, le query che utilizzano combinazioni e aggregazioni. Confrontare i runtime per le varie opzioni di progettazione. Quando si confrontano i runtime di una query, non tenere in conto il primo runtime della query perché include il tempo di compilazione. 

**DS\$1DIST\$1NONE**  
Non è necessaria alcuna ridistribuzione, perché le sezioni corrispondenti vengono posizionate sui nodi di calcolo. Solitamente si avrà una sola fase DS\$1DIST\$1NONE, la combinazione tra la tabella dei fatti e una tabella dimensionale. 

**DS\$1DIST\$1ALL\$1NONE**  
Non è necessaria alcuna ridistribuzione, perché la tabella di combinazione interna utilizza DISTSTYLE ALL. L'intera tabella si trova su ogni nodo. 

**DS\$1DIST\$1INNER**  
La tabella interna viene ridistribuita. 

**DS\$1DIST\$1OUTER**  
La tabella esterna viene ridistribuita. 

**DS\$1BCAST\$1INNER**  
Una copia di tutta la tabella interna viene trasmessa a tutti i nodi di calcolo. 

**DS\$1DIST\$1ALL\$1INNER**  
Tutta la tabella interna viene ridistribuita in una singola sezione, perché la tabella esterna utilizza DISTSTYLE ALL.

**DS\$1DIST\$1BOTH**  
Entrambe le tabelle vengono ridistribuite. 

**DS\$1DIST\$1ERR**  
Quando nella tabella non è selezionato uno stile di distribuzione.

DS\$1DIST\$1NONE e DS\$1DIST\$1ALL\$1NONE vanno bene. Indicano che non è stata necessaria alcuna ridistribuzione per quella fase, perché tutte le combinazioni erano posizionate. 

DS\$1DIST\$1INNER significa che la fase probabilmente avrà un costo relativamente alto, perché la tabella interna è stata ridistribuita sui nodi. DS\$1DIST\$1INNER indica che la tabella esterna è già stata propriamente distribuita sulla chiave di combinazione. Imposta la chiave di distribuzione della tabella interna sulla chiave di combinazione per convertirla in DS\$1DIST\$1NONE. In alcuni casi, la distribuzione della tabella interna sulla chiave di combinazione non è possibile, perché la tabella esterna non è distribuita sulla chiave di combinazione. In questo caso, valutare se utilizzare la distribuzione ALL per la tabella interna. Se la tabella non viene aggiornata frequentemente o ampiamente, oltre a essere troppo grande per portare alti costi di ridistribuzione, modificare lo stile di distribuzione su ALL e riprovare. Le clausole di distribuzione ALL incrementano i tempi di caricamento, quindi se esegui nuovi test, includi il tempo di caricamento nei fattori di valutazione. 

DS\$1DIST\$1ALL\$1INNER non va bene. Ciò significa che tutta la tabella interna viene ridistribuita in una singola sezione, perché la tabella esterna utilizza DISTSTYLE ALL, in modo che una copia di tutta la tabella esterna venga posizionata su ogni nodo. Questo comporta un'esecuzione seriale inefficiente della combinazione su un singolo nodo, anziché trarre vantaggio dal runtime parallelo che utilizza tutti i nodi. DISTSTYLE ALL dovrebbe essere utilizzata solo per la tabella di combinazione interna. Per la tabella esterna invece, specifica una chiave di distribuzione o utilizza la distribuzione EVEN.

DS\$1BCAST\$1INNER e DS\$1DIST\$1BOTH non vanno bene. Solitamente queste ridistribuzioni si verificano perché le tabelle non vengono combinate sulle loro chiavi di ridistribuzione. Se la tabella dei fatti non dispone ancora di una chiave di distribuzione, specifica la colonna di combinazione come la chiave di distribuzione per entrambe le tabelle. Se la tabella dei fatti ha già una chiave di distribuzione su un'altra colonna, valutare se la modifica della chiave di distribuzione per collocare questo join migliora le prestazioni complessive. Se la modifica della chiave di distribuzione della tabella esterna non dovesse essere una scelta ottimale, è possibile ottenere la collocazione specificando DISTSTYLE ALL per tutte le tabelle interne. 

 L'esempio seguente mostra una parte del piano di query con le etichette 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)
```

Dopo aver modificato la tabella dimensionale per utilizzare DISTSTYLE ALL, il piano di query per la stessa query mostra DS\$1DIST\$1ALL\$1NONE al posto di DS\$1BCAST\$1INNER. Inoltre, si verifica un significativo cambiamento in termini di costi per le fasi di combinazione. Il costo totale è `14142.59` confrontato con `3272334142.59` della query precedente.

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

# Esempio del piano di query
<a name="t_explain_plan_example"></a>

Questo esempio mostra come valutare un piano di query per scoprire le opportunità di ottimizzazione della distribuzione.

Esegui la seguente query con un comando EXPLAIN per produrre un piano di query.

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

Nel database TICKIT, SALES è una tabella dei fatti e LISTING è la sua dimensione più grande. Per collocare le tabelle, SALES viene distribuito su LISTID, che rappresenta la chiave esterna di LISTING, il quale viene distribuito sulla chiave primaria, LISTID. L'esempio seguente mostra il comando CREATE TABLE per 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));
```

Nel seguente piano di query, la fase Merge Join per la combinazione su SALES e LISTING mostra DS\$1DIST\$1NONE, che indica che non è necessaria alcuna ridistribuzione per la fase. Ad ogni modo, scorrendo il piano di query, le altre combinazioni interne mostrano DS\$1BCAST\$1INNER, il quale indica che la tabella interna viene trasmessa come parte dell'esecuzione della query. Dato che solo una coppia di tabelle può essere collocata mediante la distribuzione della chiave, cinque tabelle devono essere ritrasmesse.

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

Una soluzione è modificare le tabelle per avere 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;
```

Esegui la stessa query ancora con il comando EXPLAIN ed esamina il nuovo piano di query. Le combinazioni ora mostrano DS\$1DIST\$1ALL\$1NONE, il quale indica che non è necessaria alcuna ridistribuzione, dato che i dati sono stati distribuiti su tutti i nodi tramite 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)
```

# Esempi di distribuzione
<a name="c_Distribution_examples"></a>

I seguenti esempi mostrano come i dati vengono distribuiti secondo le opzioni che hai definito nella dichiarazione CREATE TABLE.

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

Guarda lo schema della tabella USERS nel database TICKIT. USERID è definito come la colonna SORTKEY e la colonna 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 è una buona scelta per la colonna di distribuzione su questa tabella. Se si esegue la query della vista di sistema SVV\$1DISKUSAGE, è possibile appurare che la tabella è stata distribuita in modo molto uniforme. I segmenti sono in base zero, quindi USERID è la colonna 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)
```

La tabella contiene 49.990 righe. Le colonne delle righe (num\$1values) mostrano che ogni sezione contiene approssimativamente lo stesso numero di righe. Le colonne minvalue e maxvalue mostrano l'intervallo di valori su ogni sezione. Ogni sezione include quasi l'intero intervallo di valori, quindi ci sono buone probabilità che ogni sezione partecipi all'esecuzione di una query che filtra per un intervallo di utenti. IDs

Questo esempio dimostra la distribuzione su un piccolo sistema di test. Il numero totale delle sezioni è solitamente più alto.

Se di solito esegui combinazioni o raggruppamenti mediante la colonna STATE, potresti scegliere di distribuire sulla colonna STATE. I seguenti esempi mostrano che se viene creata una nuova tabella con gli stessi dati della tabella USERS ma si imposta DISTKEY sulla colonna STATE, la distribuzione non sarà così ordinata. In questo caso, la distribuzione non è altrettanto uniforme. La sezione 0 (13.587 righe) contiene approssimativamente il 30% di righe in più rispetto alla sezione 3 (10.150 righe). In una tabella più grande, il totale della differenza di distribuzione potrebbe avere un impatto avverso sull'elaborazione di query.

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

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

Se crei una nuova tabella con gli stessi dati della tabella USERS ma imposti DISTSTYLE su EVEN, le righe saranno comunque distribuite in modo ordinato per le sezioni. 

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

Ad ogni modo, dato che la distribuzione non è basata su una colonna specifica, l'elaborazione di query può essere degradata, soprattutto se la tabella viene combinata su un'altra tabella. La mancanza di distribuzione su una colonna di combinazione, spesso influenza il tipo di operazione di combinazione che può essere eseguita in modo efficiente. Le operazioni di combinazione, aggregazione e raggruppamento sono ottimizzate quando entrambe le tabelle vengono distribuite e ordinate sulle loro rispettive colonne di combinazione.

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

Se crei una nuova tabella con gli stessi dati della tabella USERS ma imposti DISTSTYLE su ALL, tutte le righe saranno distribuite alla prima sezione di ogni nodo. 

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