

 Amazon Redshift tidak akan lagi mendukung pembuatan Python UDFs baru mulai Patch 198. Python yang ada UDFs akan terus berfungsi hingga 30 Juni 2026. Untuk informasi lebih lanjut, lihat [posting blog](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Distribusi data untuk optimasi kueri
<a name="t_Distributing_data"></a>

Saat Anda memuat data ke dalam tabel, Amazon Redshift mendistribusikan baris tabel ke masing-masing node komputasi sesuai dengan gaya distribusi tabel. Saat Anda menjalankan kueri, pengoptimal kueri mendistribusikan ulang baris ke node komputasi sesuai kebutuhan untuk melakukan gabungan dan agregasi apa pun. Tujuan dalam memilih gaya distribusi tabel adalah untuk meminimalkan dampak dari langkah redistribusi dengan menemukan data di tempat yang seharusnya sebelum kueri dijalankan.

**catatan**  
Bagian ini akan memperkenalkan Anda pada prinsip-prinsip distribusi data dalam database Amazon Redshift. Kami menyarankan Anda membuat tabel Anda dengan`DISTSTYLE AUTO`. Jika Anda melakukannya, Amazon Redshift menggunakan optimasi tabel otomatis untuk memilih gaya distribusi data. Untuk informasi selengkapnya, lihat [Optimalisasi tabel otomatis](t_Creating_tables.md). Sisa bagian ini memberikan rincian tentang gaya distribusi. 

**Topics**
+ [Konsep distribusi data](#t_data_distribution_concepts)
+ [Gaya distribusi](c_choosing_dist_sort.md)
+ [Melihat gaya distribusi](viewing-distribution-styles.md)
+ [Mengevaluasi pola kueri](t_evaluating_query_patterns.md)
+ [Menunjuk gaya distribusi](t_designating_distribution_styles.md)
+ [Mengevaluasi rencana kueri](c_data_redistribution.md)
+ [Contoh rencana kueri](t_explain_plan_example.md)
+ [Contoh distribusi](c_Distribution_examples.md)

## Konsep distribusi data
<a name="t_data_distribution_concepts"></a>

Beberapa konsep distribusi data untuk Amazon Redshift mengikuti.

 **Node dan irisan** 

 Cluster Amazon Redshift adalah sekumpulan node. Setiap node dalam cluster memiliki sistem operasi sendiri, memori khusus, dan penyimpanan disk khusus. Satu node adalah *node pemimpin*, yang mengelola distribusi data dan tugas pemrosesan kueri ke node komputasi. *Node komputasi* menyediakan sumber daya untuk melakukan tugas-tugas tersebut. 

 Penyimpanan disk untuk node komputasi dibagi menjadi beberapa *irisan*. Jumlah irisan per node tergantung pada ukuran node cluster. Semua node berpartisipasi dalam menjalankan query paralel, bekerja pada data yang didistribusikan secara merata di seluruh irisan. Untuk informasi selengkapnya tentang jumlah irisan yang dimiliki setiap ukuran node, lihat [Tentang cluster dan node di Panduan](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#rs-about-clusters-and-nodes) Manajemen *Pergeseran Merah Amazon*.

 **Redistribusi data** 

 Saat Anda memuat data ke dalam tabel, Amazon Redshift mendistribusikan baris tabel ke masing-masing irisan node sesuai dengan gaya distribusi tabel. Sebagai bagian dari rencana kueri, pengoptimal menentukan di mana blok data harus ditempatkan untuk menjalankan kueri dengan sebaik-baiknya. Data kemudian dipindahkan secara fisik, atau didistribusikan kembali, sementara kueri berjalan. Redistribusi mungkin melibatkan pengiriman baris tertentu ke node untuk bergabung atau menyiarkan seluruh tabel ke semua node. 

 Redistribusi data dapat menjelaskan sebagian besar biaya rencana kueri, dan lalu lintas jaringan yang dihasilkannya dapat memengaruhi operasi database lainnya dan memperlambat kinerja sistem secara keseluruhan. Sejauh Anda mengantisipasi tempat terbaik untuk menemukan data pada awalnya, Anda dapat meminimalkan dampak redistribusi data. 

 **Tujuan distribusi data** 

 Saat Anda memuat data ke dalam tabel, Amazon Redshift mendistribusikan baris tabel ke node komputasi dan irisan sesuai dengan gaya distribusi yang Anda pilih saat membuat tabel. Distribusi data memiliki dua tujuan utama: 
+ Untuk mendistribusikan beban kerja secara seragam di antara node di cluster. Distribusi yang tidak merata, atau kemiringan distribusi data, memaksa beberapa node untuk melakukan lebih banyak pekerjaan daripada yang lain, yang mengganggu kinerja kueri.
+ Untuk meminimalkan pergerakan data saat kueri berjalan. Jika baris yang berpartisipasi dalam gabungan atau agregat sudah ditempatkan pada node dengan baris penggabungannya di tabel lain, pengoptimal tidak perlu mendistribusikan ulang sebanyak mungkin data saat kueri dijalankan.

Strategi distribusi yang Anda pilih untuk database Anda memiliki konsekuensi penting untuk kinerja kueri, persyaratan penyimpanan, pemuatan data, dan pemeliharaan. Dengan memilih gaya distribusi terbaik untuk setiap tabel, Anda dapat menyeimbangkan distribusi data Anda dan secara signifikan meningkatkan kinerja sistem secara keseluruhan.

# Gaya distribusi
<a name="c_choosing_dist_sort"></a>

Saat Anda membuat tabel, Anda dapat menunjuk salah satu gaya distribusi berikut: AUTO, EVEN, KEY, atau ALL. 

Jika Anda tidak menentukan gaya distribusi, Amazon Redshift menggunakan distribusi AUTO.

 **Distribusi AUTO** 

Dengan distribusi AUTO, Amazon Redshift menetapkan gaya distribusi optimal berdasarkan ukuran data tabel. Misalnya, jika gaya distribusi AUTO ditentukan, Amazon Redshift awalnya menetapkan gaya distribusi ALL ke tabel kecil. Saat tabel bertambah besar, Amazon Redshift mungkin mengubah gaya distribusi menjadi KEY, memilih kunci primer (atau kolom kunci primer komposit) sebagai kunci distribusi. Jika tabel bertambah besar dan tidak ada kolom yang cocok untuk menjadi kunci distribusi, Amazon Redshift mengubah gaya distribusi menjadi EVEN. Perubahan gaya distribusi terjadi di latar belakang dengan dampak minimal pada kueri pengguna. 

Untuk melihat tindakan yang dilakukan Amazon Redshift secara otomatis untuk mengubah kunci distribusi tabel, lihat. [SVL\$1AUTO\$1WORKER\$1ACTION](r_SVL_AUTO_WORKER_ACTION.md) Untuk melihat rekomendasi terkini mengenai mengubah kunci distribusi tabel, lihat[SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS](r_SVV_ALTER_TABLE_RECOMMENDATIONS.md). 

Untuk melihat gaya distribusi yang diterapkan ke tabel, kueri tampilan katalog sistem PG\$1CLASS\$1INFO. Untuk informasi selengkapnya, lihat [Melihat gaya distribusi](viewing-distribution-styles.md). Jika Anda tidak menentukan gaya distribusi dengan pernyataan CREATE TABLE, Amazon Redshift menerapkan distribusi AUTO. 

 **Distribusi GENAP** 

 Node pemimpin mendistribusikan baris di seluruh irisan dengan cara round-robin, terlepas dari nilai di kolom tertentu. Distribusi EVEN sesuai ketika tabel tidak berpartisipasi dalam gabungan. Ini juga tepat ketika tidak ada pilihan yang jelas antara distribusi KUNCI dan distribusi SEMUA.

 **Distribusi KUNCI** 

 Baris didistribusikan sesuai dengan nilai dalam satu kolom. Node pemimpin menempatkan nilai yang cocok pada irisan simpul yang sama. Jika Anda mendistribusikan sepasang tabel pada kunci penggabungan, simpul pemimpin mengkolokasikan baris pada irisan sesuai dengan nilai di kolom penggabungan. Dengan cara ini, nilai yang cocok dari kolom umum disimpan secara fisik bersama. 

 **SEMUA distribusi** 

 Salinan seluruh tabel didistribusikan ke setiap node. Di mana distribusi EVEN atau distribusi KEY hanya menempatkan sebagian dari baris tabel pada setiap node, distribusi ALL memastikan bahwa setiap baris ditempatkan untuk setiap gabungan yang berpartisipasi dalam tabel. 

 Distribusi ALL mengalikan penyimpanan yang dibutuhkan dengan jumlah node di cluster, sehingga dibutuhkan waktu lebih lama untuk memuat, memperbarui, atau menyisipkan data ke dalam beberapa tabel. Distribusi ALL hanya sesuai untuk tabel bergerak relatif lambat; yaitu, tabel yang tidak sering diperbarui atau ekstensif. Karena biaya mendistribusikan ulang tabel kecil selama kueri rendah, tidak ada manfaat yang signifikan untuk mendefinisikan tabel dimensi kecil sebagai DISTSTYLE ALL. 

**catatan**  
 Setelah Anda menentukan gaya distribusi untuk kolom, Amazon Redshift menangani distribusi data di tingkat cluster. Amazon Redshift tidak memerlukan atau mendukung konsep partisi data dalam objek database. Anda tidak perlu membuat spasi tabel atau menentukan skema partisi untuk tabel. 

Dalam skenario tertentu, Anda dapat mengubah gaya distribusi tabel setelah dibuat. Untuk informasi selengkapnya, lihat [ALTER TABLE](r_ALTER_TABLE.md). Untuk skenario ketika Anda tidak dapat mengubah gaya distribusi tabel setelah dibuat, Anda dapat membuat ulang tabel dan mengisi tabel baru dengan salinan mendalam. Untuk informasi selengkapnya, lihat [Melakukan salinan yang dalam](performing-a-deep-copy.md)

# Melihat gaya distribusi
<a name="viewing-distribution-styles"></a>

Untuk melihat gaya distribusi tabel, kueri tampilan PG\$1CLASS\$1INFO atau tampilan SVV\$1TABLE\$1INFO.

Kolom RELEFFECTIVEDISTYLE di PG\$1CLASS\$1INFO menunjukkan gaya distribusi saat ini untuk tabel. Jika tabel menggunakan distribusi otomatis, RELEFFECTIVEDISTYLE adalah 10, 11, atau 12, yang menunjukkan apakah gaya distribusi efektif adalah AUTO (ALL), AUTO (EVEN), atau AUTO (KEY). Jika tabel menggunakan distribusi otomatis, gaya distribusi mungkin awalnya menampilkan AUTO (ALL), lalu ubah ke AUTO (EVEN) atau AUTO (KEY) saat tabel tumbuh. 

Tabel berikut memberikan gaya distribusi untuk setiap nilai dalam kolom RELEFFECTIVEDISTYLE: 


| RELEFFECTIVEDISTSTYLE | Gaya distribusi saat ini | 
| --- | --- | 
| 0 | PUN | 
| 1 | KUNCI | 
| 8 | SEMUA | 
| 10 | OTOMATIS (SEMUA) | 
| 11 | OTOMATIS (GENAP) | 
| 12 | OTOMATIS (KUNCI) | 

Kolom DISTSTYLE di SVV\$1TABLE\$1INFO menunjukkan gaya distribusi saat ini untuk tabel. Jika tabel menggunakan distribusi otomatis, DISTSTYLE adalah AUTO (ALL), AUTO (EVEN), atau AUTO (KEY).

Contoh berikut membuat empat tabel menggunakan tiga gaya distribusi dan distribusi otomatis, lalu query SVV\$1TABLE\$1INFO untuk melihat gaya distribusi. 

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

# Mengevaluasi pola kueri
<a name="t_evaluating_query_patterns"></a>

 Memilih gaya distribusi hanyalah salah satu aspek dari desain database. Pertimbangkan gaya distribusi dalam konteks keseluruhan sistem, menyeimbangkan distribusi dengan faktor penting lainnya seperti ukuran cluster, metode pengkodean kompresi, kunci pengurutan, dan kendala tabel. 

 Uji sistem Anda dengan data yang sedekat mungkin dengan data nyata. 

Untuk membuat pilihan yang baik untuk gaya distribusi, Anda harus memahami pola kueri untuk aplikasi Amazon Redshift Anda. Identifikasi kueri paling mahal di sistem Anda dan mendasarkan desain basis data awal Anda pada permintaan kueri tersebut. Faktor-faktor yang menentukan total biaya kueri termasuk berapa lama kueri dijalankan dan berapa banyak sumber daya komputasi yang dikonsumsi. Faktor lain yang menentukan biaya kueri adalah seberapa sering dijalankan, dan seberapa mengganggu kueri dan operasi database lainnya. 

 Identifikasi tabel yang digunakan oleh kueri paling mahal, dan evaluasi perannya dalam runtime kueri. Pertimbangkan bagaimana tabel digabungkan dan dikumpulkan. 

 Gunakan pedoman di bagian ini untuk memilih gaya distribusi untuk setiap tabel. Setelah Anda melakukannya, buat tabel dan muat dengan data yang sedekat mungkin dengan data nyata. Kemudian uji tabel untuk jenis kueri yang Anda harapkan untuk digunakan. Anda dapat mengevaluasi kueri menjelaskan rencana untuk mengidentifikasi peluang penyetelan. Bandingkan waktu muat, ruang penyimpanan, dan runtime kueri untuk menyeimbangkan persyaratan keseluruhan sistem Anda. 

# Menunjuk gaya distribusi
<a name="t_designating_distribution_styles"></a>

 Pertimbangan dan rekomendasi untuk menunjuk gaya distribusi di bagian ini menggunakan skema bintang sebagai contoh. Desain database Anda mungkin didasarkan pada skema bintang, beberapa varian skema bintang, atau skema yang sama sekali berbeda. Amazon Redshift dirancang untuk bekerja secara efektif dengan desain skema apa pun yang Anda pilih. Prinsip-prinsip dalam bagian ini dapat diterapkan pada skema desain apa pun. 

1.  **Tentukan kunci utama dan kunci asing untuk semua tabel Anda.** 

   Amazon Redshift tidak menerapkan batasan kunci primer dan kunci asing, tetapi pengoptimal kueri menggunakannya saat menghasilkan paket kueri. Jika Anda menyetel kunci utama dan kunci asing, aplikasi Anda harus mempertahankan validitas kunci. 

1.  **Bagikan tabel fakta dan tabel dimensi terbesarnya pada kolom umum mereka.** 

   Pilih dimensi terbesar berdasarkan ukuran kumpulan data yang berpartisipasi dalam gabungan yang paling umum, tidak hanya ukuran tabel. Jika tabel biasanya disaring, menggunakan klausa WHERE, hanya sebagian dari barisnya yang berpartisipasi dalam gabungan. Tabel semacam itu memiliki dampak yang lebih kecil pada redistribusi daripada tabel yang lebih kecil yang memberikan kontribusi lebih banyak data. Tentukan kunci utama tabel dimensi dan kunci asing yang sesuai dengan tabel fakta sebagai DISTKEY. Jika beberapa tabel menggunakan kunci distribusi yang sama, mereka juga ditempatkan dengan tabel fakta. Tabel fakta Anda hanya dapat memiliki satu kunci distribusi. Setiap tabel yang bergabung pada kunci lain tidak ditempatkan dengan tabel fakta. 

1.  **Tentukan kunci distribusi untuk tabel dimensi lainnya.** 

   Bagikan tabel pada kunci utama atau kunci asing mereka, tergantung pada bagaimana mereka paling sering bergabung dengan tabel lain. 

1.  **Evaluasi apakah akan mengubah beberapa tabel dimensi untuk menggunakan distribusi ALL.** 

   Jika tabel dimensi tidak dapat ditempatkan dengan tabel fakta atau tabel gabungan penting lainnya, Anda dapat meningkatkan kinerja kueri secara signifikan dengan mendistribusikan seluruh tabel ke semua node. Menggunakan distribusi ALL melipatgandakan kebutuhan ruang penyimpanan dan meningkatkan waktu muat dan operasi pemeliharaan, jadi Anda harus mempertimbangkan semua faktor sebelum memilih distribusi ALL. Bagian berikut menjelaskan cara mengidentifikasi kandidat untuk SEMUA distribusi dengan mengevaluasi rencana EXPLORE. 

1.  **Gunakan distribusi AUTO untuk tabel yang tersisa.** 

   Jika tabel sebagian besar didenormalisasi dan tidak berpartisipasi dalam gabungan, atau jika Anda tidak memiliki pilihan yang jelas untuk gaya distribusi lain, gunakan distribusi AUTO. 

Agar Amazon Redshift memilih gaya distribusi yang sesuai, jangan tentukan gaya distribusi secara eksplisit.

# Mengevaluasi rencana kueri
<a name="c_data_redistribution"></a>

Anda dapat menggunakan rencana kueri untuk mengidentifikasi kandidat untuk mengoptimalkan gaya distribusi. 

Setelah membuat keputusan desain awal Anda, buat tabel Anda, muat dengan data, dan uji. Gunakan kumpulan data pengujian yang sedekat mungkin dengan data nyata. Ukur waktu muat untuk digunakan sebagai dasar untuk perbandingan. 

Evaluasi kueri yang mewakili kueri paling mahal yang Anda harapkan untuk dijalankan, khususnya kueri yang menggunakan gabungan dan agregasi. Bandingkan runtime untuk berbagai opsi desain. Saat Anda membandingkan runtime, jangan hitung saat pertama kali kueri dijalankan, karena runtime pertama menyertakan waktu kompilasi. 

**DS\$1DIST\$1TIDAK ADA**  
Tidak diperlukan redistribusi, karena irisan yang sesuai ditempatkan pada node komputasi. Anda biasanya hanya memiliki satu langkah DS\$1DIST\$1NONE, gabungan antara tabel fakta dan satu tabel dimensi. 

**DS\$1DIST\$1ALL\$1NONE**  
Tidak diperlukan redistribusi, karena tabel gabungan bagian dalam menggunakan DISTSTYLE ALL. Seluruh tabel terletak di setiap node. 

**DS\$1DIST\$1INNER**  
Meja bagian dalam didistribusikan kembali. 

**DS\$1DIST\$1OUTER**  
Tabel luar didistribusikan kembali. 

**DS\$1BCAST\$1INNER**  
Salinan seluruh tabel bagian dalam disiarkan ke semua node komputasi. 

**DS\$1DIST\$1ALL\$1INNER**  
Seluruh tabel bagian dalam didistribusikan kembali ke satu irisan karena tabel luar menggunakan DISTSTYLE ALL.

**DS\$1DIST\$1KEDUANYA**  
Kedua tabel didistribusikan kembali. 

**DS\$1DIST\$1ERR**  
Ketika tabel tidak memiliki gaya distribusi yang dipilih.

DS\$1DIST\$1NONE dan DS\$1DIST\$1ALL\$1NONE bagus. Mereka menunjukkan bahwa tidak ada distribusi yang diperlukan untuk langkah itu karena semua gabungan ditempatkan. 

DS\$1DIST\$1INNER berarti bahwa langkah tersebut mungkin memiliki biaya yang relatif tinggi karena tabel bagian dalam didistribusikan kembali ke node. DS\$1DIST\$1INNER menunjukkan bahwa tabel luar sudah didistribusikan dengan benar pada kunci gabungan. Atur kunci distribusi tabel bagian dalam ke kunci gabungan untuk mengonversinya menjadi DS\$1DIST\$1NONE. Dalam beberapa kasus, mendistribusikan tabel bagian dalam pada kunci gabungan tidak dimungkinkan karena tabel luar tidak didistribusikan pada kunci gabungan. Jika ini masalahnya, evaluasi apakah akan menggunakan distribusi ALL untuk tabel bagian dalam. Jika tabel tidak sering diperbarui atau ekstensif, dan cukup besar untuk membawa biaya redistribusi yang tinggi, ubah gaya distribusi menjadi ALL dan uji lagi. Semua distribusi menyebabkan peningkatan waktu muat, jadi ketika Anda menguji ulang, sertakan waktu muat dalam faktor evaluasi Anda. 

DS\$1DIST\$1ALL\$1INNER tidak bagus. Ini berarti bahwa seluruh tabel bagian dalam didistribusikan kembali ke satu irisan karena tabel luar menggunakan DISTYLE ALL, sehingga salinan dari seluruh tabel luar terletak di setiap node. Ini menghasilkan runtime serial yang tidak efisien dari gabungan pada satu node, alih-alih memanfaatkan runtime paralel menggunakan semua node. DISTSTYLE ALL dimaksudkan untuk digunakan hanya untuk tabel gabungan bagian dalam. Sebagai gantinya, tentukan kunci distribusi atau gunakan distribusi genap untuk tabel luar.

DS\$1BCAST\$1INNER dan DS\$1DIST\$1BOTH tidak bagus. Biasanya redistribusi ini terjadi karena tabel tidak bergabung pada kunci distribusinya. Jika tabel fakta belum memiliki kunci distribusi, tentukan kolom penggabungan sebagai kunci distribusi untuk kedua tabel. Jika tabel fakta sudah memiliki kunci distribusi di kolom lain, evaluasi apakah mengubah kunci distribusi untuk mengkolokasi gabungan ini meningkatkan kinerja keseluruhan. Jika mengubah kunci distribusi tabel luar bukanlah pilihan yang optimal, Anda dapat mencapai kolokasi dengan menentukan DISTYLE ALL untuk tabel bagian dalam. 

 Contoh berikut menunjukkan sebagian dari rencana query dengan label DS\$1BCAST\$1INNER dan 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)
```

Setelah mengubah tabel dimensi untuk menggunakan DISTSTYLE ALL, rencana kueri untuk kueri yang sama menunjukkan DS\$1DIST\$1ALL\$1NONE sebagai pengganti DS\$1BCAST\$1INNER. Juga, ada perubahan dramatis dalam biaya relatif untuk langkah-langkah bergabung. Total biaya `14142.59` dibandingkan `3272334142.59` dengan permintaan sebelumnya.

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

# Contoh rencana kueri
<a name="t_explain_plan_example"></a>

Contoh ini menunjukkan bagaimana mengevaluasi rencana kueri untuk menemukan peluang untuk mengoptimalkan distribusi.

Jalankan query berikut dengan perintah EXPLOW untuk menghasilkan rencana 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;
```

Dalam database TICKIT, PENJUALAN adalah tabel fakta dan LISTING adalah dimensi terbesarnya. Untuk menyusun tabel, PENJUALAN didistribusikan di LISTID, yang merupakan kunci asing untuk LISTING, dan LISTING didistribusikan pada kunci utamanya, LISTID. Contoh berikut menunjukkan perintah CREATE TABLE untuk PENJUALAN dan 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));
```

Dalam paket kueri berikut, langkah Gabung Gabung untuk bergabung di SALES dan LISTING menunjukkan DS\$1DIST\$1NONE, yang menunjukkan bahwa tidak diperlukan redistribusi untuk langkah tersebut. Namun, naik rencana kueri, gabungan bagian dalam lainnya menunjukkan DS\$1BCAST\$1INNER, yang menunjukkan bahwa tabel bagian dalam disiarkan sebagai bagian dari eksekusi kueri. Karena hanya satu pasang tabel yang dapat ditempatkan menggunakan distribusi kunci, lima tabel harus disiarkan ulang.

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

Salah satu solusinya adalah mengubah tabel menjadi 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;
```

Jalankan kueri yang sama dengan EXPLORE lagi, dan periksa rencana kueri baru. Gabungan sekarang menunjukkan DS\$1DIST\$1ALL\$1NONE, menunjukkan bahwa tidak diperlukan redistribusi karena data didistribusikan ke setiap node menggunakan DISTYLE 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)
```

# Contoh distribusi
<a name="c_Distribution_examples"></a>

Contoh berikut menunjukkan bagaimana data didistribusikan sesuai dengan opsi yang Anda tentukan dalam pernyataan CREATE TABLE.

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

Lihatlah skema tabel USERS di database TICKIT. USERID didefinisikan sebagai kolom SORTKEY dan kolom 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 adalah pilihan yang baik untuk kolom distribusi pada tabel ini. Jika Anda menanyakan tampilan sistem SVV\$1DISKUSAGE, Anda dapat melihat bahwa tabel didistribusikan dengan sangat merata. Nomor kolom berbasis nol, jadi USERID adalah kolom 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)
```

Tabel berisi 49.990 baris. Kolom baris (num\$1values) menunjukkan bahwa setiap irisan berisi jumlah baris yang hampir sama. Kolom minvalue dan maxvalue menunjukkan rentang nilai pada setiap irisan. Setiap irisan mencakup hampir seluruh rentang nilai, jadi ada kemungkinan besar setiap irisan berpartisipasi dalam menjalankan kueri yang memfilter untuk berbagai pengguna. IDs

Contoh ini menunjukkan distribusi pada sistem uji kecil. Jumlah total irisan biasanya jauh lebih tinggi.

Jika Anda biasanya bergabung atau mengelompokkan menggunakan kolom STATE, Anda dapat memilih untuk mendistribusikan pada kolom STATE. Contoh berikut menunjukkan kasus di mana Anda membuat tabel baru dengan data yang sama dengan tabel USERS tetapi mengatur DISTKEY ke kolom STATE. Dalam hal ini, distribusinya tidak genap. Slice 0 (13.587 baris) memegang sekitar 30 persen lebih banyak baris daripada slice 3 (10.150 baris). Dalam tabel yang jauh lebih besar, jumlah kemiringan distribusi ini dapat berdampak buruk pada pemrosesan kueri.

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

## Contoh DISTSTYLE BAHKAN
<a name="c_Distribution_examples-diststyle-even-example"></a>

Jika Anda membuat tabel baru dengan data yang sama dengan tabel USERS tetapi mengatur DISTSTYLE ke EVEN, baris selalu didistribusikan secara merata di seluruh irisan. 

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

Namun, karena distribusi tidak didasarkan pada kolom tertentu, pemrosesan kueri dapat terdegradasi, terutama jika tabel bergabung dengan tabel lain. Kurangnya distribusi pada kolom bergabung sering mempengaruhi jenis operasi gabungan yang dapat dilakukan secara efisien. Operasi gabungan, agregasi, dan pengelompokan dioptimalkan saat kedua tabel didistribusikan dan diurutkan pada kolom penggabungannya masing-masing.

## DISTSTYLE SEMUA contoh
<a name="c_Distribution_examples-diststyle-all-example"></a>

Jika Anda membuat tabel baru dengan data yang sama dengan tabel USERS tetapi mengatur DISTSTYLE ke ALL, semua baris didistribusikan ke irisan pertama dari setiap node. 

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