

 Amazon Redshift ne prendra plus en charge la création de nouveaux Python à UDFs partir du patch 198. UDFs Le Python existant continuera de fonctionner jusqu'au 30 juin 2026. Pour plus d’informations, consultez le [ billet de blog ](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Distribution de données pour l’optimisation des requêtes
<a name="t_Distributing_data"></a>

Lorsque vous chargez des données dans une table, Amazon Redshift distribue les lignes de la table à chacun des nœuds de calcul en fonction du style de distribution de la table. Lorsque vous exécutez une requête, l’optimiseur de requête redistribue les lignes sur les nœuds de calcul en fonction des besoins afin d’effectuer les jointures et les agrégations. Le choix d’un style de distribution de table a pour objectif de minimiser l’impact de l’étape de redistribution en plaçant les données où elles doivent être avant que l’exécution de la requête.

**Note**  
Cette section vous présente les principes de distribution des données dans une base de données Amazon Redshift. Nous vous recommandons de créer vos tables avec `DISTSTYLE AUTO`. Si vous procédez ainsi, Amazon Redshift utilise l’optimisation automatique des tables pour choisir le style de distribution des données. Pour plus d'informations, consultez [Optimisation automatique des tables](t_Creating_tables.md). Le reste de cette section fournit des détails sur les styles de distribution. 

**Topics**
+ [Concepts de distribution de données](#t_data_distribution_concepts)
+ [Styles de distribution](c_choosing_dist_sort.md)
+ [Affichage des styles de distribution](viewing-distribution-styles.md)
+ [Évaluation des modèles de requêtes](t_evaluating_query_patterns.md)
+ [Détermination des styles de distribution](t_designating_distribution_styles.md)
+ [Évaluation du plan de requête](c_data_redistribution.md)
+ [Exemple de plan de requête](t_explain_plan_example.md)
+ [Exemples de distribution](c_Distribution_examples.md)

## Concepts de distribution de données
<a name="t_data_distribution_concepts"></a>

Voici quelques concepts de distribution de données pour Amazon Redshift.

 **Nœuds et tranches** 

 Un cluster Amazon Redshift est un ensemble de nœuds. Chaque nœud du cluster a ses propres système d’exploitation, mémoire dédiée et stockage sur disque dédié. Un des nœud est le *nœud principal*, qui gère la distribution des données et des tâches de traitement des requêtes dans les nœuds de calcul. Les *nœuds de calcul* fournissent les ressources nécessaires à l’exécution de ces tâches. 

 Le stockage sur disque d’un nœud de calcul est divisé en un certain nombre de *tranches*. Le nombre de tranches par nœud dépend de la taille de nœud du cluster. Les nœuds participent tous à l’exécution de requêtes parallèles, en travaillant sur des données réparties aussi uniformément que possible sur les tranches. Pour plus d'informations sur le nombre de tranches pour chaque taille de nœud, consultez la rubrique [À propos des clusters et nœuds](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#rs-about-clusters-and-nodes) dans le *Guide de la gestion du cluster Amazon Redshift*.

 **Redistribution des données** 

 Lorsque vous chargez des données dans une table, Amazon Redshift distribue les lignes de la table sur chacune des tranches de nœuds en fonction du style de distribution de la table. Dans le cadre d’un plan de requête, l’optimiseur détermine où les blocs de données doivent être situés pour exécuter au mieux la requête. Les données sont ensuite déplacées physiquement, ou redistribuées, pendant l’exécution de la requête. La redistribution peut impliquer l’envoi de lignes spécifiques aux nœuds pour joindre ou diffuser une table entière sur tous les nœuds. 

 La redistribution de données peut représenter une partie importante du coût d’un plan de requête, et le trafic réseau qu’elle génère peut affecter d’autres opérations de base de données et ralentir les performances globales du système. Tant que vous prévoyez le meilleur emplacement pour situer les données à l’origine, vous pouvez réduire l’impact de la redistribution des données. 

 **Objectifs de la distribution de données** 

 Lorsque vous chargez des données dans une table, Amazon Redshift distribue les lignes de la table sur les nœuds de calcul et les tranches en fonction du style de distribution que vous avez choisi lorsque vous avez créé la table. La distribution de données a deux objectifs principaux : 
+ Distribuer la charge de travail de manière uniforme entre les nœuds du cluster. La distribution inégale, ou l’asymétrie de la distribution de données, oblige certains nœuds à travailler plus que d’autres, ce qui nuit aux performances des requêtes.
+ Minimiser les déplacements de données lors de l’exécution d’une requête. Si les lignes qui participent aux jointures ou aux agrégats sont déjà colocalisées sur les nœuds avec leurs lignes de jonction dans d’autres tables, l’optimiseur n’a pas besoin de redistribuer autant de données lors de l’exécution des requêtes.

La stratégie de distribution que vous choisissez pour votre base de données a des conséquences importantes sur les performance des requêtes, les besoins en stockage, le chargement des données et la maintenance. En choisissant le meilleur style de distribution pour chaque table, vous pouvez équilibrer la distribution de vos données et améliorer considérablement les performances globales du système.

# Styles de distribution
<a name="c_choosing_dist_sort"></a>

Lorsque vous créez une table, vous pouvez indiquer l’un des styles de distribution suivants : AUTO, EVEN, KEY ou ALL. 

Si vous ne spécifiez pas de style de distribution, Amazon Redshift utilise la distribution AUTO.

 **Distribution AUTO** 

Avec la distribution AUTO, Amazon Redshift attribue un style de distribution optimal en fonction de la taille des données de la table. Par exemple, si le style de distribution AUTO est spécifié, Amazon Redshift affecte initialement le style de distribution ALL à une petite table. Lorsque la table s’agrandit, Amazon Redshift peut modifier le style de distribution sur KEY et choisir la clé primaire (ou une colonne de la clé primaire composite) comme clé de distribution. Si la table s’agrandit et qu’aucune des colonnes ne peut être la clé de distribution, Amazon Redshift change le style de distribution sur EVEN. La modification de style de distribution se produit en arrière-plan et son impact sur les requêtes des utilisateurs est minimal. 

Pour afficher les actions qu’Amazon Redshift a effectuées automatiquement pour modifier une clé de distribution de table, consultez [SVL\$1AUTO\$1WORKER\$1ACTION](r_SVL_AUTO_WORKER_ACTION.md). Pour afficher les recommandations actuelles concernant la modification de la clé de distribution d’une table, consultez [SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS](r_SVV_ALTER_TABLE_RECOMMENDATIONS.md). 

Pour afficher le style de distribution appliqué à une table, interrogez la vue du catalogue système PG\$1CLASS\$1INFO. Pour plus d'informations, consultez [Affichage des styles de distribution](viewing-distribution-styles.md). Si vous ne spécifiez pas de style de distribution avec l’instruction CREATE TABLE, Amazon Redshift applique la distribution AUTO. 

 **Distribution EVEN** 

 Le nœud principal distribue les lignes entre les tranches selon le principe du tourniquet (round robin), quelles que soient les valeurs d’une colonne donnée. La distribution Even est appropriée lorsqu’une table ne participe pas aux jointures. Elle est également appropriée lorsqu’il n’y a pas de choix clair entre une distribution KEY et une distribution ALL.

 **Distribution KEY** 

 Les lignes sont distribuées en fonction des valeurs dans une colonne. Le nœud principal place des valeurs correspondantes sur la même tranche de nœud. Si vous distribuez une paire de tables sur les clés de jonction, le nœud principal colocalise les lignes sur les tranches en fonction des valeurs des colonnes de jonction. De cette façon, les valeurs correspondantes des colonnes communes sont physiquement stockées ensemble. 

 **Distribution ALL** 

 Une copie de la table complète est distribuée à chaque nœud. Là où la distribution EVEN ou la distribution KEY place uniquement une partie des lignes de la table sur chaque nœud, la distribution ALL vérifie que chaque ligne est colocalisée pour chaque jointure à laquelle la table participe. 

 La distribution ALL multiplie le stockage requis par le nombre de nœuds du cluster. Il faut donc beaucoup plus de temps pour charger, mettre à jour ou insérer des données dans plusieurs tables. La distribution ALL convient uniquement aux tables relativement lentes ; c’est-à-dire les tables qui ne sont pas mises à jour fréquemment ou de façon extensive. Le coût de la redistribution de petites tables au cours d’une requête étant faible, il n’y a pas d’avantage significatif à définir des petites tables de dimension comme DISTSTYLE ALL. 

**Note**  
 Une fois que vous avez spécifié un style de distribution pour une colonne, Amazon Redshift gère la distribution des données au niveau du cluster. Amazon Redshift ne requiert ni ne prend en charge le concept de partitionnement des données au sein des objets de la base de données. Vous n’avez pas besoin de créer des tablespaces ou de définir des schémas de partitionnement pour les tables. 

Dans certains scénarios, vous pouvez modifier le style de distribution d’une table une fois qu’elle a été créée. Pour plus d'informations, consultez [ALTER TABLE](r_ALTER_TABLE.md). Pour les scénarios dans lesquels vous ne pouvez pas modifier le style de distribution d’une table après sa création, vous pouvez recréer la table et la remplir avec une copie complète. Pour plus d'informations, consultez [Exécution d’une copie complète](performing-a-deep-copy.md)

# Affichage des styles de distribution
<a name="viewing-distribution-styles"></a>

Pour afficher le style de distribution d’une table, interrogez la vue PG\$1CLASS\$1INFO ou SVV\$1TABLE\$1INFO.

La colonne RELEFFECTIVEDISTSTYLE de PG\$1CLASS\$1INFO indique le style de distribution actuel pour la table. Si la table utilise la distribution automatique, RELEFFECTIVEDISTSTYLE a pour valeur 10, 11 ou 12, ce qui indique si le style de distribution effectif est AUTO (ALL), AUTO (EVEN) ou AUTO (KEY). Si la table utilise la distribution automatique, le style de distribution peut initialement afficher AUTO (ALL), puis passer à AUTO (EVEN) ou AUTO (KEY) lorsque la table se développe. 

La table suivante donne le style de distribution pour chaque valeur de la colonne RELEFFECTIVEDISTSTYLE : 


| RELEFFECTIVEDISTSTYLE | Style de distribution actuel | 
| --- | --- | 
| 0 | EVEN | 
| 1 | KEY | 
| 8 | ALL | 
| 10 | AUTO (ALL) | 
| 11 | AUTO (EVEN) | 
| 12 | AUTO (KEY) | 

La colonne DISTSTYLE dans SVV\$1TABLE\$1INFO indique le style de distribution actuel de la table. Si la table utilise la distribution automatique, DISTSTYLE a pour valeur AUTO (ALL), AUTO (EVEN) ou AUTO (KEY).

L’exemple suivant crée quatre tables en utilisant les trois styles de distribution et la distribution automatique, puis interroge SVV\$1TABLE\$1INFO pour afficher les styles de distribution. 

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

# Évaluation des modèles de requêtes
<a name="t_evaluating_query_patterns"></a>

 Le choix des styles de distribution n’est qu’un des aspects de la conception de base de données. Prenez les styles de distribution dans le contexte du système entier, en équilibrant la distribution avec d’autres facteurs importants tels que la taille du cluster, les méthodes d’encodage de compression, les clés de tri et les contraintes de table. 

 Testez votre système avec des données qui sont aussi proches que possible des données réelles. 

Pour faire de bons choix en matière de styles de distribution, vous devez comprendre les modèles de requête de votre application Amazon Redshift. Identifiez les requêtes les plus coûteuses de votre système et fondez votre conception de base de données initiale sur les exigences de ces requêtes. Les facteurs qui déterminent le coût total d’une requête comprennent la durée d’exécution de la requête et les ressources informatiques qu’elle consomme. Les autres facteurs qui déterminent le coût d’une requête sont la fréquence d’exécution et la perturbation des autres requêtes et des opérations de la base de données. 

 Identifiez les tables utilisées par les requêtes les plus coûteuses et évaluez leur rôle dans la durée d’exécution des requêtes. Réfléchissez à la manière dont les tables sont jointes et regroupées. 

 Utilisez les instructions fournies dans cette section pour choisir un style de distribution pour chaque table. Une fois cela fait, créez les tables et chargez-les avec des données aussi proches que possible des données réelles. Testez ensuite les tables pour les types de requêtes que vous pensez utiliser. Vous pouvez évaluer les plans EXPLAIN de la requête pour identifier des opportunités de réglage. Comparez les temps de chargement, l’espace de stockage et les durées d’exécution des requêtes pour équilibrer les configurations requises de votre système. 

# Détermination des styles de distribution
<a name="t_designating_distribution_styles"></a>

 Les considérations et recommandations relatives à la désignation des styles distribution dans cette section sont basées sur un schéma en étoile à titre d’exemple. La conception de votre base de données peut être basée sur un schéma en étoile, une variante de ce schéma ou un schéma totalement différent. Amazon Redshift est conçu pour fonctionner efficacement avec n’importe quel conception de schéma, à votre choix. Les principes de cette section peuvent être appliqués à n’importe quel schéma de conception. 

1.  **Spécifiez la clé primaire et les clés étrangères de toutes vos tables.** 

   Amazon Redshift n’applique pas les contraintes de clés primaires et de clés étrangères, mais l’optimiseur de requêtes les utilise lorsqu’il génère des plans de requêtes. Si vous définissez les clés primaires et les clés étrangères, votre application doit gérer la validité des clés. 

1.  **Distribuez la table des faits et sa plus grande table de dimension sur leurs colonnes communes.** 

   Choisissez la dimension la plus grande en fonction de la taille du jeu de données qui participe à la jointure la plus courante, et pas seulement de la taille de la table. Si une table est généralement filtrée, à l’aide d’une clause WHERE, seule une partie de ses lignes participe à la jointure. Une telle table a moins d’impact sur la redistribution qu’une table plus petite qui comporte davantage de données. Désignez la clé primaire de la table de dimension et la clé étrangère correspondante de la table des faits en tant que DISTKEY. Si plusieurs tables utilisent la même clé de distribution, elles seront également colocalisées avec la table des faits. Votre table de faits peut n’avoir qu’une seule clé de distribution. Toutes les tables qui sont jointes à une autre clé de distribution ne sont pas colocalisées avec la table des faits. 

1.  **Désignez des clés de distribution pour les autres tables de dimension.** 

   Distribuez les tables sur leurs clés primaires ou leurs clés étrangères, en fonction de la manière dont elles sont jointes le plus souvent avec d’autres tables. 

1.  **Évaluez s’il faut modifier certaines des tables de dimension pour utiliser la distribution ALL.** 

   Si une table de dimension ne peut pas être colocalisée avec la table des faits ou d’autres tables de jointure importantes, il vous est possible d’améliorer considérablement les performances des requêtes en distribuant la totalité de la table sur tous les nœuds. La distribution ALL multiplie les besoins en espace de stockage et augmente les temps de chargement et les opérations de maintenance. Vous devez donc évaluer tous les facteurs avant de choisir la distribution ALL. La section suivante explique comment identifier les candidats à la distribution ALL en évaluant le plan EXPLAIN. 

1.  **Utilisez la distribution AUTO pour les tables restantes.** 

   Si une table est largement dénormalisée et ne participe pas à des jointures, ou si vous n’avez pas fait de choix arrêté sur un autre style de distribution, utilisez la distribution AUTO. 

Pour laisser Amazon Redshift choisir le style de distribution approprié, ne spécifiez pas explicitement de style de distribution.

# Évaluation du plan de requête
<a name="c_data_redistribution"></a>

Vous pouvez utiliser les plans de requête pour identifier des candidats à l’optimisation du style de distribution. 

Après avoir pris vos décisions de conception initiales, créez vos tables, chargez-les avec des données et testez-les. Utilisez un ensemble de données de test aussi proche que possible des données réelles. Mesurez les temps de chargement à utiliser comme référence pour les comparaisons. 

Évaluez les requêtes qui sont représentatives des requêtes les plus coûteuses que vous vous attendez à exécuter, en particulier les requêtes qui utilisent des jointures et des agrégations. Comparez les durées d’exécution pour différentes options de conception. Lorsque vous comparez les durées d’exécution, ne comptez pas la première fois que la requête est exécutée, car la première exécution inclut le temps de compilation. 

**DS\$1DIST\$1NONE**  
Aucun redistribution n’est obligatoire, car les tranches correspondantes sont situées sur les nœuds de calcul. Vous n’avez généralement qu’une seule étape DS\$1DIST\$1NONE, la jointure entre la table de faits et une table de dimension. 

**DS\$1DIST\$1ALL\$1NONE**  
Aucun redistribution n’est obligatoire, car la table de jointure interne a utilisé DISTSTYLE ALL. La totalité de la table se trouve sur chaque nœud. 

**DS\$1DIST\$1INNER**  
La table interne est redistribuée. 

**DS\$1DIST\$1OUTER**  
La table externe est redistribuée. 

**DS\$1BCAST\$1INNER**  
Une copie de la totalité de la table interne est diffusée à tous les nœuds de calcul. 

**DS\$1DIST\$1ALL\$1INNER**  
La totalité de la table interne est redistribué à une seule tranche, car la table externe utilise DISTSTYLE ALL.

**DS\$1DIST\$1BOTH**  
Les deux tables sont redistribuées. 

**DS\$1DIST\$1ERR**  
Lorsqu’aucun style de distribution n’est sélectionné dans la table.

DS\$1DIST\$1NONE et DS\$1DIST\$1ALL\$1NONE sont corrects. Ils indiquent qu’aucune distribution n’a été requise pour cette étape, car toutes les jointures sont colocalisées. 

DS\$1DIST\$1INNER signifie que l’étape aura probablement un coût relativement élevé, car la table interne est redistribuée aux nœuds. DS\$1DIST\$1INNER indique que la table externe est déjà correctement distribuée sur la clé de jointure. Définissez la clé de distribution de la table interne sur la clé de jointure pour convertir celle-ci en DS\$1DIST\$1NONE. Dans certains cas, la distribution de la table interne sur la clé de jointure n’est pas possible parce que la table externe n’est pas distribuée sur la clé de jointure. Si c’est le cas, évaluez s’il faut utiliser la distribution ALL pour la table interne. Si la table n’est pas mise à jour fréquemment ou de manière extensive, et qu’elle est suffisamment grande pour supporter un coût de redistribution élevé, changez le style de distribution à ALL et testez à nouveau. La distribution ALL entraîne des temps de charge supérieurs. Par conséquent, lorsque vous refaites le test, incluez le temps de chargement dans vos facteurs d’évaluation. 

DS\$1DIST\$1ALL\$1INNER n’est pas correct. Cela signifie que la totalité de la table interne est redistribué à une seule tranche, car la table externe utilise DISTSTYLE ALL, de sorte qu’une copie de la totalité de la table externe est située sur chaque nœud. Il en découle une exécution en série inefficace de la jointure sur un seul nœud, au lieu de tirer parti de l’exécution en parallèle sur l’ensemble des nœuds. DISTSTYLE ALL est conçu pour être utilisé uniquement pour la table de jointure interne. Au lieu de cela, spécifiez une clé de distribution ou utilisez la distribution uniforme pour la table externe.

DS\$1BCAST\$1INNER et DS\$1DIST\$1BOTH ne sont pas corrects. En général, ces redistributions surviennent parce que les tables ne sont pas jointes sur leurs clés de distribution. Si la table des faits ne dispose pas déjà d’une clé de distribution, définissez la colonne de jointure comme clé de distribution pour les deux tables. Si la table de faits a déjà une clé de distribution sur une autre colonne, évaluez si le fait de changer la clé de distribution pour colocaliser cette jointure améliore les performances globales. Si la modification de la clé de distribution de la table externe n’est pas un choix optimal, vous pouvez obtenir la collocation en spécifiant DISTSTYLE ALL pour la table interne. 

 L’exemple suivant illustre une partie d’un plan de requête avec les étiquettes DS\$1BCAST\$1INNER et 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)
```

Après avoir modifié les tables de dimension afin d’utiliser DISTSTYLE ALL, le plan de requête de la même requête affiche DS\$1DIST\$1ALL\$1NONE à la place de DS\$1BCAST\$1INNER. De plus, le coût relatif des étapes de la jointure ont considérablement changé. Le coût total est de `14142.59`, alors que celui de la requête précédente était de `3272334142.59`.

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

# Exemple de plan de requête
<a name="t_explain_plan_example"></a>

Cet exemple illustre la façon d’évaluer un plan de requête pour trouver des opportunités permettant d’optimiser la distribution.

Exécutez la requête suivante avec une commande EXPLAIN pour obtenir un plan de requête.

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

Dans la base de données TICKIT, SALES est une table de faits et LISTING constitue sa dimension la plus grande. Pour colocaliser les tables, SALES est distribuée sur LISTID, qui est la clé étrangère de LISTING, qui est distribuée sur sa clé primaire, LISTID. L’exemple suivant présente les commandes CREATE TABLE pour SALES et 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));
```

Dans le plan de requête suivant, l’étape Joindre par fusion de la jointure sur SALES et LISTING affiche DS\$1DIST\$1NONE, ce qui signifie qu’aucune redistribution n’est nécessaire pour cette étape. Toutefois, en évoluant dans le plan de requête, les autres jointures internes affichent DS\$1BCAST\$1INNER, ce qui signifie que la table interne est diffusée dans le cadre de l’exécution des requêtes. Du fait qu’une seule paire de tables peut être colocalisée à l’aide de la distribution de clés, cinq tables doivent être rediffusées.

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

Une solution consiste à modifier les tables de sorte qu’elles contiennent 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;
```

Réexécutez la même requête avec EXPLAIN et examinez le nouveau plan de requête. Les jointures affichent à présent DS\$1DIST\$1ALL\$1NONE, ce qui signifie qu’aucune redistribution n’est nécessaire, car les données ont été distribuées à chaque nœud à l’aide de 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)
```

# Exemples de distribution
<a name="c_Distribution_examples"></a>

Les exemples suivants illustrent le type de distribution des données selon les options que vous définissez dans l’instruction CREATE TABLE.

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

Regardez le schéma de la table USERS dans la base de données TICKIT. USERID est défini comme la colonne SORTKEY et la colonne 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 est un bon choix pour la colonne de distribution de cette table. Si vous interrogez la vue système SVV\$1DISKUSAGE, vous pouvez voir que la table est distribuée de manière très uniforme. Les nombres de colonnes sont de base zéro, USERID est donc la colonne 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 table contient 49 990 lignes. La colonne (num\$1values) des lignes affiche que chaque tranche contient à peu près le même nombre de lignes. Les colonnes minvalue et maxvalue affichent la plage de valeurs sur chaque tranche. Chaque tranche inclut la quasi-totalité de la plage de valeurs. Il y a donc de fortes chances que chaque tranche participe à l'exécution d'une requête filtrant pour un groupe d'utilisateurs IDs.

Cet exemple illustre la distribution sur un petit système de test. Le nombre total de tranches est généralement beaucoup plus élevé.

Si vous utilisez habituellement la colonne STATE pour effectuer une jointure ou un regroupement, vous pouvez choisir de distribuer sur la colonne STATE. L’exemple suivant illustre un cas où vous créez une table avec les mêmes données que la table USERS mais où vous définissez la DISTKEY sur la colonne STATE. Dans ce cas, la distribution n’est pas aussi régulière. La tranche 0 (13 587 lignes) contient environ 30 % de lignes en plus que la tranche 3 (10 150 lignes). Dans une table beaucoup plus grande, ce degré d’asymétrie de la distribution peut avoir un impact négatif sur le traitement des requêtes.

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

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

Si vous créez une table avec les mêmes données que la table USERS, mais que vous définissez DISTSTYLE sur EVEN, les lignes sont toujours distribuées uniformément entre les tranches. 

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

Cependant, du fait que la distribution n’est pas basée sur une colonne spécifique, le traitement des requêtes peut être dégradé, surtout si la table est jointe à d’autres tables. L’absence de distribution sur une colonne de jointure influence souvent le type d’opération de jointure qui peut être effectué de manière efficace. Les jointures, les agrégations et les opérations de regroupement sont optimisées lorsque les deux tables sont distribuées et triées sur leurs colonnes de jointure respectives.

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

Si vous créez une table avec les mêmes données que la table USERS, mais que vous définissez DISTSTYLE sur ALL, toutes les lignes sont distribuées à la première tranche de chaque nœud. 

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