

 Amazon Redshift tidak akan lagi mendukung penggunaan Python UDF setelah 30 Juni 2026. Kami akan mulai menegakkannya secara bertahap. Untuk informasi lebih lanjut tentang detail opsi akhir masa pakai dan migrasi Python, 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/) yang diterbitkan pada 30 Juni 2025. 

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

# Membuat dan menafsirkan rencana kueri
<a name="c-the-query-plan"></a>

Anda dapat menggunakan rencana kueri untuk mendapatkan informasi tentang operasi individual yang diperlukan untuk menjalankan kueri. Sebelum Anda bekerja dengan rencana kueri, sebaiknya Anda terlebih dahulu memahami bagaimana Amazon Redshift menangani kueri pemrosesan dan membuat rencana kueri. Untuk informasi selengkapnya, lihat [Perencanaan kueri dan alur kerja pelaksanaan](c-query-planning.md).

Untuk membuat rencana kueri, jalankan [EXPLAIN](r_EXPLAIN.md) perintah diikuti oleh teks kueri yang sebenarnya. Paket kueri memberi Anda informasi berikut:
+ Operasi apa yang dilakukan mesin eksekusi, membaca hasilnya dari bawah ke atas.
+ Jenis langkah apa yang dilakukan setiap operasi.
+ Tabel dan kolom mana yang digunakan dalam setiap operasi.
+ Berapa banyak data yang diproses dalam setiap operasi, dalam hal jumlah baris dan lebar data dalam byte.
+ Biaya relatif operasi. *Biaya * adalah ukuran yang membandingkan waktu eksekusi relatif dari langkah-langkah dalam rencana. Biaya tidak memberikan informasi yang tepat tentang waktu eksekusi aktual atau konsumsi memori, juga tidak memberikan perbandingan yang berarti antara rencana eksekusi. Ini memberi Anda indikasi operasi mana dalam kueri yang menghabiskan sumber daya paling banyak.

Perintah EXPLAIN tidak benar-benar menjalankan kueri. Ini hanya menunjukkan rencana yang dijalankan Amazon Redshift jika kueri dijalankan dalam kondisi operasi saat ini. Jika Anda mengubah skema atau data untuk tabel dan menjalan [MENGANALISA](r_ANALYZE.md) kannya lagi untuk memperbarui metadata statistik, rencana kueri mungkin berbeda.

Output rencana kueri oleh EXPLAIN adalah tampilan eksekusi kueri tingkat tinggi yang disederhanakan. Itu tidak menggambarkan detail pemrosesan kueri paralel. Untuk melihat informasi terperinci, jalankan kueri itu sendiri, lalu dapatkan informasi ringkasan kueri dari tampilan SVL\_QUERY\_SUMMARY atau SVL\_QUERY\_REPORT. Untuk informasi selengkapnya tentang menggunakan tampilan ini, lihat[Menganalisis ringkasan kueri](c-analyzing-the-query-summary.md).

Contoh berikut menunjukkan output EXPLAIN untuk kueri GROUP BY sederhana pada tabel EVENT:

```
explain select eventname, count(*) from event group by eventname;

                            QUERY PLAN
-------------------------------------------------------------------
XN HashAggregate  (cost=131.97..133.41 rows=576 width=17)
  ->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=17)
```

EXPLAIN mengembalikan metrik berikut untuk setiap operasi:

**Biaya**  
Nilai relatif yang berguna untuk membandingkan operasi dalam rencana. Biaya terdiri dari dua nilai desimal yang dipisahkan oleh dua periode, misalnya`cost=131.97..133.41`. Nilai pertama, dalam hal ini 131,97, memberikan biaya relatif untuk mengembalikan baris pertama untuk operasi ini. Nilai kedua, dalam hal ini 133,41, memberikan biaya relatif untuk menyelesaikan operasi. Biaya dalam rencana kueri bersifat kumulatif saat Anda membaca rencana, jadi HashAggregate biaya dalam contoh ini (131.97.. 133.41) termasuk biaya Seq Scan di bawahnya (0.00.. 87.98).

**Baris**  
Perkiraan jumlah baris yang akan dikembalikan. Dalam contoh ini, pemindaian diharapkan mengembalikan 8798 baris. HashAggregate Operator sendiri diharapkan mengembalikan 576 baris (setelah nama peristiwa duplikat dibuang dari kumpulan hasil).  
Perkiraan baris didasarkan pada statistik yang tersedia yang dihasilkan oleh perintah ANALYZE. Jika ANALYZE belum dijalankan baru-baru ini, estimasi kurang dapat diandalkan.

**Lebar**  
Perkiraan lebar baris rata-rata, dalam byte. Dalam contoh ini, baris rata-rata diharapkan lebar 17 byte.

## JELASKAN operator
<a name="EXPLAIN-operators"></a>

Bagian ini menjelaskan secara singkat operator yang paling sering Anda lihat dalam output EXPLAIN. Untuk daftar lengkap operator, lihat [EXPLAIN](r_EXPLAIN.md) di bagian Perintah SQL.

### Operator pemindaian berurutan
<a name="scan-operator"></a>

Operator pemindaian sekuensial (Seq Scan) menunjukkan pemindaian tabel. Seq Scan memindai setiap kolom dalam tabel secara berurutan dari awal hingga akhir dan mengevaluasi batasan kueri (dalam klausa WHERE) untuk setiap baris.

### Bergabunglah dengan operator
<a name="join-operators"></a>

Amazon Redshift memilih operator gabungan berdasarkan desain fisik tabel yang digabungkan, lokasi data yang diperlukan untuk bergabung, dan persyaratan khusus kueri itu sendiri.
+ **Lingkaran bersarang **

  Gabungan yang paling tidak optimal, loop bersarang digunakan terutama untuk sambungan silang (produk Cartesian) dan beberapa gabungan ketidaksetaraan.
+ **Hash Join dan Hash **

  Biasanya lebih cepat daripada gabungan loop bersarang, gabungan hash dan hash digunakan untuk join dalam dan join luar kiri dan kanan. Operator ini digunakan saat menggabungkan tabel di mana kolom gabungan bukan kunci distribusi * dan kunci * pengurutan. Operator hash membuat tabel hash untuk tabel bagian dalam di join; operator hash join membaca tabel luar, men-hash kolom penggabungan, dan menemukan kecocokan di tabel hash bagian dalam.
+ **Gabungkan Gabung **

  Biasanya gabungan tercepat, gabungan gabungan digunakan untuk gabungan dalam dan gabungan luar. Gabungan gabungan tidak digunakan untuk gabungan penuh. Operator ini digunakan saat menggabungkan tabel di mana kolom gabungan adalah kunci distribusi * dan kunci peng * urutan, dan ketika kurang dari 20 persen tabel penggabungan tidak disortir. Ini membaca dua tabel yang diurutkan secara berurutan dan menemukan baris yang cocok. Untuk melihat persentase baris yang tidak disortir, kueri tabel [SVV\_TABLE\_INFO](r_SVV_TABLE_INFO.md) sistem.
+ **Gabung Spasial **

  Biasanya penggabungan cepat berdasarkan kedekatan data spasial, digunakan untuk `GEOMETRY` dan `GEOGRAPHY` tipe data.

### Operator agregat
<a name="aggregate-operators"></a>

Rencana kueri menggunakan operator berikut dalam kueri yang melibatkan fungsi agregat dan operasi GROUP BY.
+ **Agregat **

  Operator untuk fungsi agregat skalar seperti AVG dan SUM.
+ **HashAggregate**

  Operator untuk fungsi agregat yang dikelompokkan yang tidak disortir.
+ **GroupAggregate**

  Operator untuk fungsi agregat yang dikelompokkan yang diurutkan.

### Sortir operator
<a name="sort-operators"></a>

Paket kueri menggunakan operator berikut ketika kueri harus mengurutkan atau menggabungkan kumpulan hasil.
+ **Urutkan **

  Mengevaluasi klausa ORDER BY dan operasi pengurutan lainnya, seperti pengurutan yang diperlukan oleh kueri dan gabungan UNION, kueri SELECT DISTINCT, dan fungsi jendela.
+ **Menggabungkan **

  Menghasilkan hasil akhir yang diurutkan menurut hasil diurutkan menengah yang berasal dari operasi paralel.

### Operator UNION, INTERSECT, dan EXCEPT
<a name="UNION-INTERSECT-and-EXCEPT-operators"></a>

Rencana kueri menggunakan operator berikut untuk kueri yang melibatkan operasi set dengan UNION, INTERSECT, dan EXCEPT.
+ **Subkueri **

  Digunakan untuk menjalankan query UNION.
+ **Hash Berpotongan Berbeda **

  Digunakan untuk menjalankan query INTERSECT.
+ **SetOp Kecuali **

  Digunakan untuk menjalankan query EXCEPT (atau MINUS).

### Operator lainnya
<a name="other-operators"></a>

Operator berikut juga sering muncul dalam output EXPLAIN untuk kueri rutin.
+ **Unik **

  Menghapus duplikat untuk kueri SELECT DISTINCT dan query UNION.
+ **Batasi **

  Memproses klausa LIMIT.
+ **Jendela **

  Menjalankan fungsi jendela.
+ **Hasil **

  Menjalankan fungsi skalar yang tidak melibatkan akses tabel apa pun.
+ **Subrencana **

  Digunakan untuk subquery tertentu.
+ **Jaringan **

  Mengirim hasil perantara ke node pemimpin untuk diproses lebih lanjut.
+ **Terwujud **

  Menyimpan baris untuk input ke gabungan loop bersarang dan beberapa gabungan gabungan.

## Bergabung dalam EXPLAIN
<a name="joins-in-EXPLAIN"></a>

Pengoptimal kueri menggunakan jenis gabungan yang berbeda untuk mengambil data tabel, tergantung pada struktur kueri dan tabel yang mendasarinya. Output EXPLAIN mereferensikan jenis gabungan, tabel yang digunakan, dan cara data tabel didistribusikan di seluruh cluster untuk menggambarkan bagaimana query diproses.

### Contoh tipe gabungan
<a name="join-types"></a>

Contoh berikut menunjukkan jenis gabungan yang berbeda yang dapat digunakan pengoptimal kueri. Jenis gabungan yang digunakan dalam rencana kueri tergantung pada desain fisik tabel yang terlibat.

#### Contoh: Hash menggabungkan dua tabel
<a name="hash-join-two-tables"></a>

Kueri berikut bergabung dengan EVENT dan CATEGORY pada kolom CATID. CATID adalah kunci distribusi dan pengurutan untuk CATEGORY tetapi tidak untuk EVENT. Gabungan hash dilakukan dengan EVENT sebagai tabel luar dan CATEGORY sebagai tabel dalam. Karena CATEGORY adalah tabel yang lebih kecil, perencana menyiarkan salinannya ke node komputasi selama pemrosesan kueri dengan menggunakan DS\_BCAST\_INNER. Biaya gabungan dalam contoh ini menyumbang sebagian besar biaya kumulatif paket.

```
explain select * from category, event where category.catid=event.catid;

                               QUERY PLAN
-------------------------------------------------------------------------
 XN Hash Join DS_BCAST_INNER  (cost=0.14..6600286.07 rows=8798 width=84)
   Hash Cond: ("outer".catid = "inner".catid)
   ->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=35)
   ->  XN Hash  (cost=0.11..0.11 rows=11 width=49)
         ->  XN Seq Scan on category  (cost=0.00..0.11 rows=11 width=49)
```

**catatan**  
Indentasi selaras untuk operator dalam output EXPLAIN terkadang menunjukkan bahwa operasi tersebut tidak bergantung satu sama lain dan dapat dimulai secara paralel. Dalam contoh sebelumnya, meskipun pemindaian pada tabel EVENT dan operasi hash disejajarkan, pemindaian EVENT harus menunggu sampai operasi hash selesai sepenuhnya.

#### Contoh: Gabungkan gabungkan dua tabel
<a name="merge-join-two-tables"></a>

Kueri berikut juga menggunakan SELECT \*, tetapi bergabung dengan SALES dan LISTING pada kolom LISTID, di mana LISTID telah ditetapkan sebagai kunci distribusi dan pengurutan untuk kedua tabel. Gabungan gabungan dipilih, dan tidak ada redistribusi data yang diperlukan untuk bergabung (DS\_DIST\_NONE).

```
explain select * from sales, listing where sales.listid = listing.listid;
QUERY PLAN
-----------------------------------------------------------------------------
XN Merge Join DS_DIST_NONE  (cost=0.00..6285.93 rows=172456 width=97)
  Merge Cond: ("outer".listid = "inner".listid)
  ->  XN Seq Scan on listing  (cost=0.00..1924.97 rows=192497 width=44)
  ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=53)
```

Contoh berikut menunjukkan berbagai jenis gabungan dalam kueri yang sama. Seperti pada contoh sebelumnya, SALES dan LISTING digabungkan, tetapi tabel ketiga, EVENT, harus digabungkan dengan hash dengan hasil gabungan gabungan. Sekali lagi, hash join menimbulkan biaya siaran.

```
explain select * from sales, listing, event
where sales.listid = listing.listid and sales.eventid = event.eventid;
                                  QUERY PLAN
----------------------------------------------------------------------------
XN Hash Join DS_BCAST_INNER  (cost=109.98..3871130276.17 rows=172456 width=132)
  Hash Cond: ("outer".eventid = "inner".eventid)
  ->  XN Merge Join DS_DIST_NONE  (cost=0.00..6285.93 rows=172456 width=97)
        Merge Cond: ("outer".listid = "inner".listid)
        ->  XN Seq Scan on listing  (cost=0.00..1924.97 rows=192497 width=44)
        ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=53)
  ->  XN Hash  (cost=87.98..87.98 rows=8798 width=35)
        ->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=35)
```

#### Contoh: Gabung, agregasi, dan urutkan
<a name="join-aggregate-and-sort-example"></a>

Kueri berikut menjalankan gabungan hash dari tabel SALES dan EVENT, diikuti dengan operasi agregasi dan pengurutan untuk memperhitungkan fungsi SUM yang dikelompokkan dan klausa ORDER BY. Operator pengurutan awal berjalan secara paralel pada node komputasi. Kemudian operator Jaringan mengirimkan hasil ke node pemimpin, di mana operator Merge menghasilkan hasil akhir yang diurutkan.

```
explain select eventname, sum(pricepaid) from sales, event 
where sales.eventid=event.eventid group by eventname
order by 2 desc;
                                           QUERY PLAN
---------------------------------------------------------------------------------
 XN Merge  (cost=1002815366604.92..1002815366606.36 rows=576 width=27)
  Merge Key: sum(sales.pricepaid)
  ->  XN Network  (cost=1002815366604.92..1002815366606.36 rows=576 width=27)
        Send to leader
        ->  XN Sort  (cost=1002815366604.92..1002815366606.36 rows=576 width=27)
              Sort Key: sum(sales.pricepaid)
              ->  XN HashAggregate  (cost=2815366577.07..2815366578.51 rows=576 width=27)
                    ->  XN Hash Join DS_BCAST_INNER  (cost=109.98..2815365714.80 rows=172456 width=27)
                          Hash Cond: ("outer".eventid = "inner".eventid)
                          ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=14)
                          ->  XN Hash  (cost=87.98..87.98 rows=8798 width=21)
                                ->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=21)
```

### Redistribusi data
<a name="data-redistribution"></a>

Output EXPLAIN untuk join juga menentukan metode bagaimana data dipindahkan di sekitar cluster untuk memfasilitasi penggabungan. Pergerakan data ini dapat berupa siaran atau redistribusi. Dalam siaran, nilai data dari satu sisi gabungan disalin dari setiap node komputasi ke setiap node komputasi lainnya, sehingga setiap node komputasi berakhir dengan salinan lengkap data. Dalam redistribusi, nilai data yang berpartisipasi dikirim dari irisan mereka saat ini ke irisan baru (mungkin pada node yang berbeda). Data biasanya didistribusikan kembali untuk mencocokkan kunci distribusi tabel lain yang berpartisipasi dalam gabungan jika kunci distribusi itu adalah salah satu kolom penggabungan. Jika tidak ada tabel yang memiliki kunci distribusi pada salah satu kolom penggabungan, kedua tabel didistribusikan atau tabel bagian dalam disiarkan ke setiap node.

Output EXPLAIN juga mereferensikan tabel dalam dan luar. Tabel bagian dalam dipindai terlebih dahulu, dan muncul lebih dekat bagian bawah rencana kueri. Meja bagian dalam adalah tabel yang diperiksa untuk pertandingan. Biasanya disimpan dalam memori, biasanya tabel sumber untuk hashing, dan jika memungkinkan, adalah tabel yang lebih kecil dari keduanya yang digabungkan. Tabel luar adalah sumber baris untuk dicocokkan dengan tabel bagian dalam. Biasanya dibaca dari disk. Pengoptimal kueri memilih tabel dalam dan luar berdasarkan statistik database dari menjalankan perintah ANALYZE terbaru. Urutan tabel dalam klausa FROM dari kueri tidak menentukan tabel mana yang dalam dan mana yang luar.

Gunakan atribut berikut dalam rencana kueri untuk mengidentifikasi bagaimana data dipindahkan untuk memfasilitasi kueri:
+ **DS\_BCAST\_INNER **

  Salinan seluruh tabel bagian dalam disiarkan ke semua node komputasi.
+ **DS\_DIST\_ALL\_NONE **

  Tidak diperlukan redistribusi, karena tabel bagian dalam telah didistribusikan ke setiap node menggunakan DISTSTYLE ALL.
+ **DS\_DIST\_NONE **

  Tidak ada tabel yang didistribusikan kembali. Gabungan yang dikolokasikan dimungkinkan karena irisan yang sesuai digabungkan tanpa memindahkan data antar node.
+ **DS\_DIST\_INNER **

  Tabel bagian dalam didistribusikan kembali.
+ **DS\_DIST\_LUAR **

  Tabel luar didistribusikan kembali.
+ **DS\_DIST\_ALL\_INNER **

  Seluruh tabel bagian dalam didistribusikan kembali ke satu irisan karena tabel luar menggunakan DISTSTYLE ALL.
+ **DS\_DIST\_KEDUANYA **

  Kedua tabel didistribusikan kembali.