

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

# Optimalkan kueri


Gunakan teknik pengoptimalan kueri yang dijelaskan di bagian ini untuk membuat kueri berjalan lebih cepat atau sebagai solusi untuk kueri yang melebihi batas sumber daya di Athena.

## Optimalkan bergabung


Ada banyak strategi berbeda untuk mengeksekusi gabungan dalam mesin kueri terdistribusi. Dua yang paling umum adalah gabungan hash terdistribusi dan kueri dengan kondisi gabungan yang kompleks.

### Dalam gabungan hash terdistribusi, tempatkan tabel besar di sebelah kiri, tabel kecil di sebelah kanan


Jenis gabungan yang paling umum menggunakan perbandingan kesetaraan sebagai kondisi gabungan. Athena menjalankan jenis join ini sebagai gabungan hash terdistribusi.

Dalam gabungan hash terdistribusi, mesin membangun tabel pencarian (tabel hash) dari salah satu sisi gabungan. Sisi ini disebut *sisi build*. Catatan sisi build didistribusikan di seluruh node. Setiap node membangun tabel pencarian untuk subsetnya. Sisi lain dari gabungan, yang disebut *sisi probe*, kemudian dialirkan melalui node. Catatan dari sisi probe didistribusikan di atas node dengan cara yang sama seperti sisi build. Ini memungkinkan setiap node untuk melakukan gabungan dengan mencari catatan yang cocok di tabel pencariannya sendiri.

Ketika tabel pencarian yang dibuat dari sisi build gabungan tidak sesuai dengan memori, kueri bisa gagal. Bahkan jika ukuran total sisi build kurang dari memori yang tersedia, kueri dapat gagal jika distribusi catatan memiliki kemiringan yang signifikan. Dalam kasus ekstrim, semua catatan dapat memiliki nilai yang sama untuk kondisi gabungan dan harus masuk ke dalam memori pada satu node. Bahkan kueri dengan sedikit kemiringan dapat gagal jika satu set nilai dikirim ke node yang sama dan nilainya bertambah hingga lebih dari memori yang tersedia. Node memang memiliki kemampuan untuk menumpahkan catatan ke disk, tetapi tumpahan memperlambat eksekusi kueri dan tidak cukup untuk mencegah kueri gagal.

Athena mencoba menyusun ulang gabungan untuk menggunakan relasi yang lebih besar sebagai sisi probe, dan relasi yang lebih kecil sebagai sisi build. Namun, karena Athena tidak mengelola data dalam tabel, ia memiliki informasi yang terbatas dan sering harus mengasumsikan bahwa tabel pertama lebih besar dan tabel kedua lebih kecil.

Saat menulis gabungan dengan kondisi gabungan berbasis ekualitas, asumsikan bahwa tabel di sebelah kiri `JOIN` kata kunci adalah sisi probe dan tabel di sebelah kanan adalah sisi build. Pastikan bahwa tabel yang tepat, sisi build, adalah tabel yang lebih kecil. Jika tidak memungkinkan untuk membuat sisi build dari join cukup kecil agar sesuai dengan memori, pertimbangkan untuk menjalankan beberapa kueri yang menggabungkan subset tabel build.

### Gunakan EXPLOW untuk menganalisis kueri dengan gabungan kompleks


Kueri dengan kondisi gabungan yang kompleks (misalnya, kueri yang menggunakan`LIKE`,`>`, atau operator lain), seringkali menuntut komputasi. Dalam kasus terburuk, setiap catatan dari satu sisi bergabung harus dibandingkan dengan setiap catatan di sisi lain dari bergabung. Karena waktu eksekusi tumbuh dengan kuadrat jumlah catatan, kueri tersebut berisiko melebihi waktu eksekusi maksimum.

Untuk mengetahui bagaimana Athena akan menjalankan kueri Anda sebelumnya, Anda dapat menggunakan pernyataan tersebut. `EXPLAIN` Untuk informasi selengkapnya, lihat [Menggunakan EXPLAIN dan EXPLAIN ANALYZE di Athena](athena-explain-statement.md) dan [Pahami Athena JELASKAN hasil pernyataan](athena-explain-statement-understanding.md).

## Kurangi ruang lingkup fungsi jendela, atau hapus


Karena fungsi jendela adalah operasi intensif sumber daya, mereka dapat membuat kueri berjalan lambat atau bahkan gagal dengan pesan Sumber daya yang habis Kueri pada faktor skala ini. Fungsi jendela menyimpan semua catatan yang mereka operasikan dalam memori untuk menghitung hasilnya. Ketika jendela sangat besar, fungsi jendela bisa kehabisan memori.

Untuk memastikan kueri Anda berjalan dalam batas memori yang tersedia, kurangi ukuran jendela tempat fungsi jendela Anda beroperasi. Untuk melakukannya, Anda dapat menambahkan `PARTITIONED BY` klausa atau mempersempit cakupan klausa partisi yang ada.

### Gunakan fungsi non-jendela


Terkadang kueri dengan fungsi jendela dapat ditulis ulang tanpa fungsi jendela. Misalnya, alih-alih menggunakan `row_number` untuk menemukan `N` catatan teratas, Anda dapat menggunakan `ORDER BY` dan`LIMIT`. [https://trino.io/docs/current/functions/aggregate.html#min_by](https://trino.io/docs/current/functions/aggregate.html#min_by)

Misalnya, Anda memiliki kumpulan data dengan pembaruan dari sensor. Sensor secara berkala melaporkan status baterainya dan menyertakan beberapa metadata seperti lokasi. Jika Anda ingin mengetahui status baterai terakhir untuk setiap sensor dan lokasinya, Anda dapat menggunakan kueri ini:

```
SELECT sensor_id,
       arbitrary(location) AS location,
       max_by(battery_status, updated_at) AS battery_status
FROM sensor_readings
GROUP BY sensor_id
```

Karena metadata seperti lokasi sama untuk setiap catatan, Anda dapat menggunakan `arbitrary` fungsi untuk memilih nilai apa pun dari grup. 

Untuk mendapatkan status baterai terakhir, Anda dapat menggunakan `max_by` fungsinya. `max_by`Fungsi memilih nilai untuk kolom dari catatan di mana nilai maksimum kolom lain ditemukan. Dalam hal ini, ia mengembalikan status baterai untuk catatan dengan waktu pembaruan terakhir dalam grup. Kueri ini berjalan lebih cepat dan menggunakan lebih sedikit memori daripada kueri setara dengan fungsi jendela. 

## Optimalkan agregasi


Ketika Athena melakukan agregasi, Athena mendistribusikan catatan di seluruh node pekerja menggunakan kolom dalam klausa. `GROUP BY` Untuk membuat tugas mencocokkan catatan ke grup seefisien mungkin, node berusaha menyimpan catatan dalam memori tetapi menumpahkannya ke disk jika perlu.

Ini juga merupakan ide yang baik untuk menghindari memasukkan kolom berlebihan dalam `GROUP BY` klausa. Karena lebih sedikit kolom membutuhkan lebih sedikit memori, kueri yang menggambarkan grup menggunakan lebih sedikit kolom lebih efisien. Kolom numerik juga menggunakan lebih sedikit memori daripada string. Misalnya, saat Anda menggabungkan kumpulan data yang memiliki ID kategori numerik dan nama kategori, gunakan hanya kolom ID kategori dalam klausa. `GROUP BY`

Terkadang kueri menyertakan kolom dalam `GROUP BY` klausa untuk mengatasi fakta bahwa kolom harus menjadi bagian dari `GROUP BY` klausa atau ekspresi agregat. Jika aturan ini tidak diikuti, Anda dapat menerima pesan kesalahan seperti berikut:

 EXPRESSION\$1NOT\$1AGGREGATE: baris 1:8: 'kategori' harus berupa ekspresi agregat atau muncul di klausa GROUP BY 

Untuk menghindari keharusan menambahkan kolom redundan ke `GROUP BY` klausa, Anda dapat menggunakan fungsi [arbitrer](https://trino.io/docs/current/functions/aggregate.html#arbitrary), seperti pada contoh berikut.

```
SELECT country_id,
       arbitrary(country_name) AS country_name,
       COUNT(*) AS city_count
FROM world_cities
GROUP BY country_id
```

`ARBITRARY`Fungsi mengembalikan nilai arbitrer dari grup. Fungsi ini berguna ketika Anda tahu semua catatan dalam grup memiliki nilai yang sama untuk kolom, tetapi nilainya tidak mengidentifikasi grup.

## Optimalkan kueri N teratas


`ORDER BY`Klausa mengembalikan hasil query dalam urutan diurutkan. Athena menggunakan pengurutan terdistribusi untuk menjalankan operasi pengurutan secara paralel pada beberapa node.

Jika Anda tidak benar-benar membutuhkan hasil Anda untuk diurutkan, hindari menambahkan `ORDER BY` klausa. Selain itu, hindari `ORDER BY` menambahkan kueri batin jika tidak benar-benar diperlukan. Dalam banyak kasus, perencana kueri dapat menghapus penyortiran yang berlebihan, tetapi ini tidak dijamin. Pengecualian untuk aturan ini adalah jika kueri dalam melakukan `N` operasi teratas, seperti menemukan nilai terbaru, atau `N` paling umum. `N`

Ketika Athena melihat `ORDER BY` bersama`LIMIT`, ia memahami bahwa Anda menjalankan `N` kueri teratas dan menggunakan operasi khusus yang sesuai.

**catatan**  
Meskipun Athena juga sering dapat mendeteksi fungsi jendela seperti `row_number` itu menggunakan top`N`, kami merekomendasikan versi yang lebih sederhana yang menggunakan `ORDER BY` dan. `LIMIT` Untuk informasi selengkapnya, lihat [Kurangi ruang lingkup fungsi jendela, atau hapus](#performance-tuning-optimizing-window-functions).

## Sertakan hanya kolom yang diperlukan


Jika Anda tidak benar-benar membutuhkan kolom, jangan sertakan dalam kueri Anda. Semakin sedikit data yang harus diproses oleh kueri, semakin cepat ia akan berjalan. Ini mengurangi jumlah memori yang dibutuhkan dan jumlah data yang harus dikirim antar node. Jika Anda menggunakan format file kolumnar, mengurangi kolom angka juga mengurangi jumlah data yang dibaca dari Amazon S3.

Athena tidak memiliki batasan spesifik pada jumlah kolom dalam hasil, tetapi bagaimana kueri dijalankan membatasi kemungkinan ukuran gabungan kolom. Ukuran gabungan kolom mencakup nama dan jenisnya.

Misalnya, kesalahan berikut disebabkan oleh relasi yang melebihi batas ukuran untuk deskriptor relasi:

 GENERIC\$1INTERNAL\$1ERROR: io.airlift.bytecode. CompilationException 

Untuk mengatasi masalah ini, kurangi jumlah kolom dalam kueri, atau buat subkueri dan gunakan yang mengambil data dalam jumlah `JOIN` yang lebih kecil. Jika Anda memiliki kueri yang dilakukan `SELECT *` di kueri terluar, Anda harus mengubah `*` ke daftar hanya kolom yang Anda butuhkan.

## Optimalkan kueri dengan menggunakan perkiraan


Athena memiliki dukungan untuk [fungsi agregat aproksimasi](https://trino.io/docs/current/functions/aggregate.html#appro) untuk menghitung nilai yang berbeda, nilai yang paling sering, persentil (termasuk perkiraan median), dan membuat histogram. Gunakan fungsi-fungsi ini setiap kali nilai yang tepat tidak diperlukan.

Tidak seperti `COUNT(DISTINCT col)` operasi, [approx\$1distinct](https://trino.io/docs/current/functions/aggregate.html#approx_distinct) menggunakan lebih sedikit memori dan berjalan lebih cepat. Demikian pula, menggunakan [numeric\$1histogram alih-alih [histogram](https://trino.io/docs/current/functions/aggregate.html#histogram)](https://trino.io/docs/current/functions/aggregate.html#numeric_histogram) menggunakan metode perkiraan dan karenanya lebih sedikit memori.

## Optimalkan LIKE


Anda dapat menggunakan `LIKE` untuk menemukan string yang cocok, tetapi dengan string panjang, ini adalah komputasi intensif. Fungsi [regexp\$1like](https://trino.io/docs/current/functions/regexp.html#regexp_like) dalam banyak kasus merupakan alternatif yang lebih cepat, dan juga memberikan lebih banyak fleksibilitas.

Seringkali Anda dapat mengoptimalkan pencarian dengan menambatkan substring yang Anda cari. Misalnya, jika Anda mencari awalan, jauh lebih baik menggunakan '*substr*%' daripada *substr* '% %'. Atau, jika Anda menggunakan`regexp_like`, '^ *substr* '.

## Gunakan UNION ALL alih-alih UNION


 `UNION ALL`dan `UNION` dua cara untuk menggabungkan hasil dari dua query menjadi satu hasil. `UNION ALL`menggabungkan catatan dari kueri pertama dengan yang kedua, dan `UNION` melakukan hal yang sama, tetapi juga menghapus duplikat. `UNION`perlu memproses semua catatan dan menemukan duplikat, yang merupakan memori dan komputasi intensif, tetapi `UNION ALL` merupakan operasi yang relatif cepat. Kecuali Anda perlu menghapus duplikat catatan, gunakan `UNION ALL` untuk kinerja terbaik.

## Gunakan UNLOAD untuk set hasil besar


Ketika hasil kueri diharapkan besar (misalnya, puluhan ribu baris atau lebih), gunakan UNLOAD untuk mengekspor hasilnya. Dalam kebanyakan kasus, ini lebih cepat daripada menjalankan kueri biasa, dan menggunakan `UNLOAD` juga memberi Anda lebih banyak kontrol atas output.

Saat kueri selesai dijalankan, Athena menyimpan hasilnya sebagai satu file CSV yang tidak terkompresi di Amazon S3. Ini membutuhkan waktu lebih lama dari`UNLOAD`, bukan hanya karena hasilnya tidak terkompresi, tetapi juga karena operasi tidak dapat diparalelkan. Sebaliknya, `UNLOAD` menulis hasil langsung dari node pekerja dan memanfaatkan sepenuhnya paralelisme cluster komputasi. Selain itu, Anda dapat mengonfigurasi `UNLOAD` untuk menulis hasil dalam format terkompresi dan dalam format file lain seperti JSON dan Parket.

Untuk informasi selengkapnya, lihat [MEMBONGKAR](unload.md). 

## Gunakan CTAS atau Glue ETL untuk mewujudkan agregasi yang sering digunakan


'Mewujudkan' kueri adalah cara mempercepat kinerja kueri dengan menyimpan hasil kueri kompleks yang telah dihitung sebelumnya (misalnya, agregasi dan gabungan) untuk digunakan kembali dalam kueri berikutnya.

Jika banyak kueri Anda menyertakan gabungan dan agregasi yang sama, Anda dapat mewujudkan subquery umum sebagai tabel baru dan kemudian menjalankan kueri terhadap tabel tersebut. Anda dapat membuat tabel baru dengan[Buat tabel dari hasil kueri (CTAS)](ctas.md), atau alat ETL khusus seperti [Glue ETL](https://aws.amazon.com/glue).

Misalnya, Anda memiliki dasbor dengan widget yang menunjukkan aspek berbeda dari kumpulan data pesanan. Setiap widget memiliki kueri sendiri, tetapi semua kueri berbagi gabungan dan filter yang sama. Tabel pesanan digabungkan dengan tabel item baris, dan ada filter untuk ditampilkan hanya tiga bulan terakhir. Jika Anda mengidentifikasi fitur umum dari kueri ini, Anda dapat membuat tabel baru yang dapat digunakan widget. Ini mengurangi duplikasi dan meningkatkan kinerja. Kerugiannya adalah Anda harus memperbarui tabel baru.

## Gunakan kembali hasil kueri


Biasanya kueri yang sama berjalan beberapa kali dalam durasi singkat. Misalnya, ini dapat terjadi ketika beberapa orang membuka dasbor data yang sama. Saat menjalankan kueri, Anda dapat memberi tahu Athena untuk menggunakan kembali hasil yang dihitung sebelumnya. Anda menentukan usia maksimum hasil yang akan digunakan kembali. Jika kueri yang sama sebelumnya dijalankan dalam jangka waktu tersebut, Athena mengembalikan hasil tersebut alih-alih menjalankan kueri lagi. *Untuk informasi selengkapnya, lihat di [Gunakan kembali hasil kueri di Athena](reusing-query-results.md) sini di *Panduan Pengguna Amazon Athena* dan [Kurangi biaya serta tingkatkan kinerja kueri dengan Penggunaan Kembali Hasil Kueri Amazon Athena](https://aws.amazon.com/blogs/big-data/reduce-cost-and-improve-query-performance-with-amazon-athena-query-result-reuse/) di AWS Blog Big Data.*