

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

# Bekerja dengan rencana Aurora DSQL EXPLY
<a name="working-with-explain-plans"></a>

Aurora DSQL menggunakan struktur rencana EXPLORE yang mirip dengan PostgreSQL, tetapi dengan penambahan kunci yang mencerminkan arsitektur terdistribusi dan model eksekusi.

Dalam dokumentasi ini, kami akan memberikan gambaran umum tentang rencana Aurora DSQL EXPLORE, menyoroti persamaan dan perbedaan dibandingkan dengan PostgreSQL. Kami akan membahas berbagai jenis operasi pemindaian yang tersedia di Aurora DSQL dan membantu Anda memahami biaya menjalankan kueri Anda.

## PostgreSQL VS Aurora DSQL JELASKAN rencana
<a name="postgresql-explain-plans"></a>

 Aurora DSQL dibangun di atas database PostgreSQL dan berbagi sebagian besar struktur rencana dengan PostgreSQL, tetapi memiliki perbedaan arsitektur utama yang mempengaruhi eksekusi dan pengoptimalan kueri:


| Fitur | PostgreSQL | Aurora DSQL | 
| --- | --- | --- | 
|  Penyimpanan Data  |  Penyimpanan Tumpukan  |  Tidak ada tumpukan, semua baris diindeks oleh pengidentifikasi unik  | 
|  Kunci Utama  |  Indeks kunci primer terpisah dari data tabel  |  Indeks kunci primer adalah tabel dengan semua kolom tambahan sebagai kolom INCLUDE  | 
|  Indeks Sekunder  |  Indeks sekunder standar  |  Bekerja sama dengan PostgreSQL, dengan kemampuan untuk menyertakan kolom non-kunci  | 
|  Kemampuan Penyaringan  |  Kondisi Indeks, Filter Tumpukan  |  Kondisi Indeks, Filter Penyimpanan, Filter Prosesor Kueri   | 
|  Jenis Pindai  |  Pemindaian Berurutan, Pemindaian Indeks, Pemindaian Hanya Indeks  |  Pemindaian Penuh, Pemindaian Hanya Indeks, Pemindaian Indeks  | 
|  Eksekusi Kueri  |  Lokal ke Database  |  Didistribusikan (komputasi dan penyimpanan terpisah)  | 

Aurora DSQL menyimpan data tabel secara langsung dalam urutan kunci primer daripada di tumpukan terpisah. Setiap baris diidentifikasi oleh kunci unik, biasanya kunci utama, yang memungkinkan database untuk mengoptimalkan pencarian lebih efisien. Perbedaan arsitektur menjelaskan mengapa Aurora DSQL sering menggunakan Index Only Scan dalam kasus di mana PostgreSQL mungkin memilih pemindaian sekuensial. 

Perbedaan utama lainnya adalah bahwa Aurora DSQL memisahkan komputasi dari penyimpanan, memungkinkan filter diterapkan sebelumnya di jalur eksekusi untuk mengurangi pergerakan data dan meningkatkan kinerja.

[Untuk selengkapnya menggunakan rencana EXPLORE dengan PostgreSQL, lihat dokumentasi PostgreSQL EXPLORE.](https://www.postgresql.org/docs/current/using-explain.html)

## Elemen kunci dalam rencana Aurora DSQL JELASKAN
<a name="explain-plan-elements"></a>

Rencana Aurora DSQL EXPLOW memberikan informasi rinci tentang bagaimana kueri dijalankan, termasuk di mana pemfilteran terjadi dan kolom mana yang diambil dari penyimpanan. Memahami keluaran ini membantu Anda mengoptimalkan kinerja kueri.

Indeks Cond  
Kondisi yang digunakan untuk menavigasi indeks. Pemfilteran paling efisien yang mengurangi data yang dipindai. Di Aurora DSQL, kondisi indeks dapat diterapkan pada beberapa lapisan rencana eksekusi.

Proyeksi  
Kolom diambil dari penyimpanan. Proyeksi yang lebih sedikit berarti kinerja yang lebih baik.

Filter Penyimpanan  
Kondisi diterapkan pada tingkat penyimpanan. Lebih efisien daripada filter prosesor kueri.

Filter Prosesor Kueri  
Kondisi diterapkan pada tingkat prosesor kueri. Memerlukan transfer semua data sebelum penyaringan, yang menghasilkan pergerakan data yang lebih tinggi dan overhead pemrosesan.

## Filter dalam Aurora DSQL
<a name="filtering-and-projection"></a>

Aurora DSQL memisahkan komputasi dari penyimpanan, yang berarti bahwa titik di mana filter diterapkan selama eksekusi kueri memiliki dampak signifikan pada kinerja. Filter yang diterapkan sebelum volume besar data ditransfer mengurangi latensi dan meningkatkan efisiensi. Semakin awal filter diterapkan, semakin sedikit data yang perlu diproses, dipindahkan, dan dipindai, menghasilkan kueri yang lebih cepat.

Aurora DSQL dapat menerapkan filter pada beberapa tahap di jalur kueri. Memahami tahapan ini adalah kunci untuk menafsirkan rencana kueri dan mengoptimalkan kinerja.


| Tingkat | Jenis Filter | Deskripsi | 
| --- | --- | --- | 
| 1 | Kondisi Indeks |  Diterapkan saat memindai indeks. Membatasi berapa banyak data yang dibaca dari penyimpanan dan mengurangi data yang dikirim ke lapisan komputasi.  | 
| 2 | Filter Penyimpanan | Diterapkan setelah data dibaca dari penyimpanan tetapi sebelum dikirim ke komputasi. Contoh di sini adalah filter pada kolom include indeks. Mengurangi transfer data tetapi bukan jumlah yang dibaca. | 
| 3 | Filter Prosesor Kueri | Diterapkan setelah data mencapai lapisan komputasi. Semua data harus ditransfer terlebih dahulu, yang meningkatkan latensi dan biaya. Saat ini, Aurora DSQL tidak dapat melakukan semua operasi penyaringan dan proyeksi pada penyimpanan, sehingga beberapa kueri mungkin terpaksa kembali ke jenis penyaringan ini. | 

# Membaca Aurora DSQL JELASKAN rencana
<a name="reading-dsql-explain-plans"></a>

Memahami cara membaca rencana EXPLORE adalah kunci untuk mengoptimalkan kinerja kueri. Di bagian ini, kita akan menelusuri contoh nyata dari rencana kueri Aurora DSQL, menunjukkan bagaimana berbagai jenis pemindaian berperilaku, menjelaskan di mana filter diterapkan, dan menyoroti peluang untuk pengoptimalan.

## Tabel sampel yang digunakan dalam contoh-contoh ini
<a name="explain-plan-sample-tables"></a>

Contoh di bawah ini merujuk dua tabel: `transaction` dan`account`.

`transaction`Tabel tidak memiliki kunci utama, yang menyebabkan Aurora DSQL melakukan pemindaian tabel penuh saat menanyakannya.

`account`Tabel memiliki indeks pada`customer_id`. Indeks ini mencakup `balance` dan `status` sebagai kolom penutup, yang memungkinkan kueri tertentu dipenuhi langsung dari indeks tanpa membaca dari tabel dasar. Namun, indeks tidak termasuk`created_at`, sehingga kueri yang merujuk kolom ini memerlukan akses tabel tambahan.

```
CREATE TABLE transaction (
    account_id uuid,
    transaction_date timestamp,
    description text
);

CREATE TABLE account (
    customer_id uuid,
    balance numeric,
    status varchar,
    created_at timestamp
);

CREATE INDEX ASYNC idx1 ON account (customer_id) INCLUDE (balance, status);
```

## Contoh Pemindaian Lengkap
<a name="full-scan-example"></a>

Aurora DSQL memiliki Pemindaian Berurutan, yang secara fungsional identik dengan PostgreSQL, serta Pemindaian Penuh. Satu-satunya perbedaan antara keduanya adalah bahwa Full Scan dapat memanfaatkan penyaringan ekstra pada penyimpanan. Karena ini, hampir selalu dipilih di atas Pemindaian Berurutan. Karena kesamaannya, kami hanya akan membahas contoh Pemindaian Penuh yang lebih menarik.

Pemindaian Penuh sebagian besar akan digunakan pada tabel tanpa kunci utama. Karena kunci primer Aurora DSQL secara default mencakup indeks penuh, Aurora DSQL kemungkinan besar akan menggunakan Index Only Scan pada kunci utama dalam banyak situasi di mana PostgreSQL akan menggunakan Sequential Scan. Seperti kebanyakan database lainnya, tabel tanpa indeks di atasnya akan berskala buruk.

```
EXPLAIN SELECT account_id FROM transaction WHERE transaction_date > '2025-01-01' AND description LIKE '%external%';
```

```
                                                   QUERY PLAN
----------------------------------------------------------------------------------------------------------------
 Full Scan (btree-table) on transaction  (cost=125100.05..177933.38 rows=33333 width=16)
   Filter: (description ~~ '%external%'::text)
   -> Storage Scan on transaction (cost=12510.05..17793.38 rows=66666 width=16)
        Projections: account_id, description
        Filters: (transaction_date > '2025-01-01 00:00:00'::timestamp without time zone)
        -> B-Tree Scan on transaction (cost=12510.05..17793.38 rows=100000 width=30)
```

Rencana ini menunjukkan dua filter yang diterapkan pada tahap yang berbeda. `transaction_date > '2025-01-01'`Kondisi ini diterapkan pada lapisan penyimpanan, mengurangi berapa banyak data yang dikembalikan. `description LIKE '%external%'`Kondisi ini diterapkan kemudian di prosesor kueri, setelah data ditransfer, membuatnya kurang efisien. Mendorong filter yang lebih selektif ke dalam lapisan penyimpanan atau indeks umumnya meningkatkan kinerja.

## Contoh Index Only Scan
<a name="index-only-scan-example"></a>

Index Only Scan adalah jenis pemindaian yang paling optimal di Aurora DSQL karena menghasilkan perjalanan pulang pergi paling sedikit ke lapisan penyimpanan dan dapat melakukan pemfilteran paling banyak. Tetapi hanya karena Anda melihat Index Only Scan tidak berarti Anda memiliki rencana terbaik. Karena semua tingkat penyaringan yang berbeda yang dapat terjadi, penting untuk tetap memperhatikan berbagai tempat penyaringan dapat terjadi.

```
EXPLAIN SELECT balance FROM account 
WHERE customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb' 
AND balance > 100 
AND status = 'pending';
```

```
                                  QUERY PLAN
-------------------------------------------------------------------------------
 Index Only Scan using idx1 on account  (cost=725.05..1025.08 rows=8 width=18)
   Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
   Filter: (balance > '100'::numeric)
   -> Storage Scan on idx1 (cost=12510.05..17793.38 rows=9 width=16)
        Projections: balance
        Filters: ((status)::text = 'pending'::text)
        -> B-Tree Scan on idx1 (cost=12510.05..17793.38 rows=10 width=30)
            Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
```

Dalam rencana ini, kondisi indeks,`customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'`), dievaluasi terlebih dahulu selama pemindaian indeks, yang merupakan tahap paling efisien karena membatasi berapa banyak data yang dibaca dari penyimpanan. Filter penyimpanan`status = 'pending'`,, diterapkan setelah data dibaca tetapi sebelum dikirim ke lapisan komputasi, mengurangi jumlah data yang ditransfer. Akhirnya, filter prosesor kueri`balance > 100`,, berjalan terakhir, setelah data dipindahkan, membuatnya paling tidak efisien. Dari jumlah tersebut, kondisi indeks memberikan kinerja terbesar karena secara langsung mengontrol berapa banyak data yang dipindai.

## Contoh Pemindaian Indeks
<a name="index-scan-example"></a>

Index Scan mirip dengan Index Only Scan, kecuali mereka memiliki langkah ekstra untuk memanggil ke tabel dasar. Karena Aurora DSQL dapat menentukan filter penyimpanan, ia dapat melakukannya baik pada panggilan indeks maupun panggilan pencarian.

Untuk memperjelas hal ini, Aurora DSQL menyajikan rencana sebagai dua node. Dengan cara ini, Anda dapat dengan jelas melihat seberapa banyak menambahkan kolom include akan membantu dalam hal baris yang dikembalikan dari penyimpanan.

```
EXPLAIN SELECT balance FROM account 
WHERE customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'
AND balance > 100 
AND status = 'pending' 
AND created_at > '2025-01-01';
```

```
                                                QUERY PLAN
----------------------------------------------------------------------------------------------------------
 Index Scan using idx1 on account  (cost=728.18..1132.20 rows=3 width=18)
   Filter: (balance > '100'::numeric)
   Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
   -> Storage Scan on idx1 (cost=12510.05..17793.38 rows=8 width=16)
        Projections: balance
        Filters: ((status)::text = 'pending'::text)
        -> B-Tree Scan on account (cost=12510.05..17793.38 rows=10 width=30)
            Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
   -> Storage Lookup on account (cost=12510.05..17793.38 rows=4 width=16)
        Filters: (created_at > '2025-01-01 00:00:00'::timestamp without time zone)
        -> B-Tree Lookup on transaction (cost=12510.05..17793.38 rows=8 width=30)
```

 Rencana ini menunjukkan bagaimana penyaringan terjadi di beberapa tahap: 
+  Kondisi indeks pada data `customer_id ` filter lebih awal. 
+ Filter penyimpanan pada `status` lebih lanjut mempersempit hasil sebelum dikirim ke komputasi. 
+ Filter prosesor kueri pada `balance` diterapkan kemudian, setelah transfer.
+ Filter pencarian `created_at` dievaluasi saat mengambil kolom tambahan dari tabel dasar. 

Menambahkan kolom yang sering digunakan sebagai `INCLUDE` bidang seringkali dapat menghilangkan pencarian ini dan meningkatkan kinerja. 

## Praktik Terbaik
<a name="best-practices"></a>
+ **Sejajarkan filter dengan kolom yang diindeks** untuk mendorong pemfilteran sebelumnya.
+ **Gunakan kolom INCLUDE** untuk mengizinkan Pemindaian Hanya Indeks dan menghindari pencarian.
+ **Validasi estimasi baris** saat menyelidiki masalah kinerja. Aurora DSQL mengelola statistik secara otomatis dengan berjalan `ANALYZE` di latar belakang berdasarkan tingkat perubahan data. Jika perkiraan tampak tidak akurat, Anda dapat menjalankan `ANALYZE` secara manual untuk menyegarkan statistik segera.
+ **Hindari kueri yang tidak diindeks** pada tabel besar untuk mencegah Pemindaian Penuh yang mahal.

# Memahami DPUs dalam EXPLY ANALYSIS
<a name="understanding-dpus-explain-analyze"></a>

Aurora DSQL menyediakan informasi Distributed Processing Unit (DPU) **tingkat pernyataan** dalam output `EXPLAIN ANALYZE VERBOSE` rencana, memberi Anda visibilitas yang lebih dalam ke biaya kueri selama pengembangan. Bagian ini menjelaskan DPUs apa dan bagaimana menafsirkannya dalam `EXPLAIN ANALYZE VERBOSE` output.

## Apa itu DPU?
<a name="what-is-dpu"></a>

Distributed Processing Unit (DPU) adalah ukuran normalisasi dari pekerjaan yang dilakukan oleh Aurora DSQL. Ini terdiri dari:
+ **ComputedPU** - Waktu yang dihabiskan untuk mengeksekusi kueri SQL
+ **ReadDPU** — Sumber daya yang digunakan untuk membaca data dari penyimpanan
+ **WriteDPU** - Sumber daya yang digunakan untuk menulis data ke penyimpanan
+ **MultiRegionWriteDPU** — Sumber daya yang digunakan untuk mereplikasi penulisan ke cluster peered dalam konfigurasi Multi-wilayah.

## Penggunaan DPU di EXPLY ANALYZE VERBOSE
<a name="dpu-usage-explain-analyze"></a>

Aurora DSQL diperluas `EXPLAIN ANALYZE VERBOSE` untuk menyertakan perkiraan penggunaan DPU tingkat pernyataan hingga akhir output. Ini memberikan visibilitas langsung ke biaya kueri, membantu Anda mengidentifikasi driver biaya beban kerja, menyesuaikan kinerja kueri, dan perkiraan penggunaan sumber daya yang lebih baik.

Contoh berikut menunjukkan bagaimana menafsirkan estimasi DPU tingkat pernyataan yang termasuk dalam EXPLORE ANALYZE VERBOSE output.

### Contoh 1: SELECT Query
<a name="select-query-example"></a>

```
EXPLAIN ANALYZE VERBOSE SELECT * FROM test_table;
```

```
QUERY PLAN
----------------------------------------------------
Index Only Scan using test_table_pkey on public.test_table  (cost=125100.05..171100.05 rows=1000000 width=36) (actual time=2.973..4.482 rows=120 loops=1)
  Output: id, context
  -> Storage Scan on test_table_pkey (cost=125100.05..171100.05 rows=1000000 width=36) (actual rows=120 loops=1)
      Projections: id, context
      -> B-Tree Scan on test_table_pkey (cost=125100.05..171100.05 rows=1000000 width=36) (actual rows=120 loops=1)
Query Identifier: qymgw1m77maoe
Planning Time: 11.415 ms
Execution Time: 4.528 ms
Statement DPU Estimate:
  Compute: 0.01607 DPU
  Read: 0.04312 DPU
  Write: 0.00000 DPU
  Total: 0.05919 DPU
```

Dalam contoh ini, pernyataan SELECT melakukan pemindaian indeks saja, sehingga sebagian besar biaya berasal dari Baca DPU (0,04312), mewakili data yang diambil dari penyimpanan dan Compute DPU (0,01607), yang mencerminkan sumber daya komputasi yang digunakan untuk memproses dan mengembalikan hasilnya. Tidak ada Write DPU karena kueri tidak mengubah data. Total DPU (0,05919) adalah jumlah dari Compute \$1 Read\$1Write.

### Contoh 2: INSERT Query
<a name="insert-query-example"></a>

```
EXPLAIN ANALYZE VERBOSE INSERT INTO test_table VALUES (1, 'name1'), (2, 'name2'), (3, 'name3');
```

```
QUERY PLAN
----------------------------------------------------
Insert on public.test_table  (cost=0.00..0.04 rows=0 width=0) (actual time=0.055..0.056 rows=0 loops=1)
  ->  Values Scan on "*VALUES*"  (cost=0.00..0.04 rows=3 width=122) (actual time=0.003..0.008 rows=3 loops=1)
        Output: "*VALUES*".column1, "*VALUES*".column2
Query Identifier: jtkjkexhjotbo
Planning Time: 0.068 ms
Execution Time: 0.543 ms
Statement DPU Estimate:
  Compute: 0.01550 DPU
  Read: 0.00307 DPU (Transaction minimum: 0.00375)
  Write: 0.01875 DPU (Transaction minimum: 0.05000)
  Total: 0.03732 DPU
```

Pernyataan ini terutama melakukan penulisan, sehingga sebagian besar biaya dikaitkan dengan Tulis DPU. Compute DPU (0,01550) mewakili pekerjaan yang dilakukan untuk memproses dan menyisipkan nilai. DPU Baca (0,00307) mencerminkan pembacaan sistem minor (untuk pencarian katalog atau pemeriksaan indeks).

Perhatikan minimum Transaksi yang ditampilkan di samping Baca dan Tulis DPUs. Ini menunjukkan biaya dasar per transaksi yang berlaku *hanya ketika operasi termasuk* membaca atau menulis. Bukan berarti setiap transaksi otomatis dikenakan biaya 0,00375 Read DPU atau 0,05 Write DPU. Sebaliknya, minimum ini diterapkan pada tingkat transaksi selama agregasi biaya dan hanya jika pembacaan atau penulisan terjadi dalam transaksi itu. Karena perbedaan ruang lingkup ini, perkiraan tingkat pernyataan `EXPLAIN ANALYZE VERBOSE` mungkin tidak sama persis dengan metrik tingkat transaksi yang dilaporkan dalam atau data penagihan. CloudWatch 

## Menggunakan Informasi DPU untuk Optimalisasi
<a name="using-dpu-information-optimization"></a>

Perkiraan DPU per pernyataan memberi Anda cara yang ampuh untuk mengoptimalkan kueri di luar waktu eksekusi. Kasus penggunaan umum meliputi:
+ **Kesadaran Biaya:** Memahami seberapa mahal kueri relatif terhadap orang lain.
+ **Optimasi Skema:** Bandingkan dampak indeks atau perubahan skema pada kinerja dan efisiensi sumber daya.
+ **Perencanaan Anggaran:** Perkirakan biaya beban kerja berdasarkan penggunaan DPU yang diamati.
+ **Perbandingan Kueri:** Evaluasi pendekatan kueri alternatif dengan konsumsi DPU relatifnya.

## Menafsirkan Informasi DPU
<a name="interpreting-dpu-information"></a>

Ingatlah praktik terbaik berikut saat menggunakan data DPU dari`EXPLAIN ANALYZE VERBOSE`:
+ **Gunakan secara terarah:** Perlakukan DPU yang dilaporkan sebagai cara untuk memahami biaya *relatif* kueri daripada kecocokan persis dengan CloudWatch metrik atau data penagihan. Perbedaan diharapkan karena `EXPLAIN ANALYZE VERBOSE` melaporkan biaya tingkat pernyataan, sementara CloudWatch agregat aktivitas tingkat transaksi. CloudWatch juga mencakup operasi latar belakang (seperti ANALISIS atau pemadatan) dan overhead transaksi (`BEGIN`/`COMMIT`) yang `EXPLAIN ANALYZE VERBOSE` sengaja dikecualikan.
+ **Variabilitas DPU di seluruh proses normal** dalam sistem terdistribusi dan tidak menunjukkan kesalahan. Faktor-faktor seperti caching, perubahan rencana eksekusi, konkurensi, atau pergeseran dalam distribusi data semuanya dapat menyebabkan kueri yang sama mengkonsumsi sumber daya yang berbeda dari satu proses ke yang berikutnya.
+ **Operasi kecil batch:** Jika beban kerja Anda mengeluarkan banyak pernyataan kecil, pertimbangkan untuk mengelompokkannya ke dalam operasi yang lebih besar (tidak melebihi 10MB). Ini mengurangi overhead pembulatan dan menghasilkan perkiraan biaya yang lebih berarti.
+ **Gunakan untuk penyetelan, bukan penagihan:** Data DPU `EXPLAIN ANALYZE VERBOSE` dirancang untuk kesadaran biaya, penyetelan kueri, dan pengoptimalan. Ini bukan metrik tingkat penagihan. Selalu mengandalkan CloudWatch metrik atau laporan penagihan bulanan untuk data biaya dan penggunaan otoritatif.