Back to IF3140 Sistem Basis Data
Materi: Query Processing and Optimization
Analisis Kinerja Query
-
EXPLAIN [QUERY];- Menampilkan rencana eksekusi (query plan) dari sebuah query tanpa menjalankannya. Berguna untuk melihat estimasi
costdan langkah-langkah yang akan diambil oleh database (misalnyaSeq Scan,Hash Join).
- Menampilkan rencana eksekusi (query plan) dari sebuah query tanpa menjalankannya. Berguna untuk melihat estimasi
-
EXPLAIN ANALYZE [QUERY];- Menjalankan query dan menampilkan rencana eksekusi beserta waktu eksekusi aktual (
actual time) dan statistik lainnya. Ini adalah alat utama untuk mengukur dan membandingkan performa query secara nyata.
- Menjalankan query dan menampilkan rencana eksekusi beserta waktu eksekusi aktual (
-
\timing- Meta-command di
psqlyang berfungsi sebagai toggle (on/off) untuk menampilkan total waktu eksekusi (Planning Time+Execution Time) setiap kali query dijalankan.
- Meta-command di
Strategi Umum Penulisan Query
Terdapat beberapa pendekatan untuk menulis query yang kompleks, masing-masing dengan kelebihan dan kekurangannya.
1. Standard INNER JOIN
Pendekatan paling umum dan seringkali mudah dibaca untuk menggabungkan data dari beberapa tabel.
-
Kelebihan:
-
Sintaks yang lugas dan standar.
-
Seringkali sangat efisien jika kolom yang di-
JOINmemiliki indeks.
-
-
Kekurangan:
- Bisa menjadi sangat panjang dan sulit dibaca jika melibatkan banyak tabel.
-- Mencari pesawat yang terbang ke PRANCIS
SELECT
a.airplane_id,
COUNT(f.to) AS total_ke_perancis
FROM
airplane a
INNER JOIN flight f ON f.airplane_id = a.airplane_id
INNER JOIN airport ap ON ap.airport_id = f.to
INNER JOIN airport_geo ag ON ap.airport_id = ag.airport_id
WHERE
ag.country = 'FRANCE'
GROUP BY
a.airplane_id
HAVING
COUNT(a.airplane_id) > 5;2. WITH Clause (Common Table Expression - CTE)
Memungkinkan Anda untuk membuat tabel sementara yang logis dalam sebuah query. Sangat baik untuk memecah masalah yang kompleks menjadi beberapa langkah yang lebih sederhana.
-
Kelebihan:
-
Modularitas & Keterbacaan: Membuat query utama lebih bersih dan mudah dipahami.
-
Filter Awal: Memungkinkan filtering atau agregasi data di awal, sehingga
JOINpada query utama memproses lebih sedikit baris.
-
-
Kekurangan:
- Terkadang dapat menimbulkan overhead atau performance penalty jika optimizer database tidak menanganinya dengan efisien.
-- Menggunakan CTE untuk menyeleksi bandara di PRANCIS terlebih dahulu
WITH france_airports AS (
SELECT ap.airport_id
FROM airport ap
INNER JOIN airport_geo ag ON ap.airport_id = ag.airport_id
WHERE ag.country = 'FRANCE'
)
SELECT
a.airplane_id,
COUNT(f.to) AS total_ke_perancis
FROM
airplane a
INNER JOIN flight f ON f.airplane_id = a.airplane_id
INNER JOIN france_airports fa ON f.to = fa.airport_id
GROUP BY
a.airplane_id
HAVING
COUNT(a.airplane_id) > 5;3. Subquery dalam WHERE Clause
Menggunakan SELECT di dalam klausa WHERE (misalnya dengan IN, EXISTS).
-
Kelebihan:
- Dapat mengurangi jumlah
JOINeksplisit pada query utama.
- Dapat mengurangi jumlah
-
Kekurangan:
- Potensi Inefisiensi: Subquery dapat dieksekusi berulang kali untuk setiap baris dari tabel luar, terutama jika tidak dioptimalkan dengan baik. Umumnya ini adalah pendekatan yang paling tidak efisien untuk dataset besar.
-- Menggunakan Subquery pada klausa WHERE
SELECT
a.airplane_id,
COUNT(f.to) AS total_ke_perancis
FROM
airplane a
INNER JOIN flight f ON f.airplane_id = a.airplane_id
WHERE
f.to IN (
SELECT ap.airport_id
FROM airport ap
INNER JOIN airport_geo ag ON ap.airport_id = ag.airport_id
WHERE ag.country = 'FRANCE'
)
GROUP BY
a.airplane_id
HAVING
COUNT(a.airplane_id) > 5;Teknik Optimasi Query
Berdasarkan analisis EXPLAIN ANALYZE, berikut adalah beberapa cara untuk menyederhanakan dan mempercepat query:
-
Hapus
JOINyang Tidak Perlu: Jika sebuah tabel di-JOINtetapi tidak ada kolomnya yang digunakan diSELECT,WHERE, atauJOINlainnya, makaJOINtersebut kemungkinan besar tidak diperlukan. -
Ganti Subquery Kompleks dengan
JOIN: Seringkali, mengubah query yang menggunakanWHERE ... IN (SELECT ...)menjadiINNER JOINlangsung akan memberikan performa yang lebih baik karena query planner dapat membuat rencana eksekusi yang lebih optimal. -
Filter Data Sedini Mungkin: Lakukan penyaringan data menggunakan
WHEREsecepat mungkin dalam proses. Menggunakan CTE untuk memfilter data sebelum melakukanJOINbesar adalah salah satu contohnya. -
Hindari
DISTINCTyang Redundan:DISTINCTmemerlukan operasi sorting atau hashing yang memakan biaya. Jika logika query (misalnyaGROUP BYpada Primary Key) sudah menjamin keunikan baris,DISTINCTtidak diperlukan. -
Ganti
LIKE '%...%'dengan=atauLIKE '...%': Jika memungkinkan, hindari penggunaan wildcard (%) di awal string karena ini mencegah penggunaan indeks pada kolom tersebut dan memaksaSeq Scan.
Contoh Skenario: Penyederhanaan Query
Kasus: Mendapatkan data pesawat (ID, tipe, nama maskapai) yang berbasis di Perancis.
Query Awal (Tidak Efisien): Menggunakan dua subquery (CTE dan WHERE IN).
WITH airplane_types AS (
SELECT DISTINCT
ap.airplane_id, at.identifier, a.airlinename, a.base_airport
FROM airplane ap
JOIN airplane_type at ON ap.type_id = at.type_id
JOIN airline a ON a.airline_id = ap.airline_id
)
SELECT ats.airplane_id, ats.identifier, ats.airlinename
FROM airplane_types ats
WHERE ats.base_airport IN (
-- Subquery kedua untuk mendapatkan bandara di Prancis
SELECT base_airport FROM airline ar JOIN airport_geo ag ON ar.base_airport = ag.airport_id WHERE country = 'FRANCE'
)
ORDER BY ats.airplane_id;Query Perbaikan (Lebih Optimal): Menggabungkan semua logika menjadi satu query dengan INNER JOIN.
SELECT
ap.airplane_id,
at.identifier,
a.airlinename
FROM
airplane ap
INNER JOIN airplane_type at ON ap.type_id = at.type_id
INNER JOIN airline a ON a.airline_id = ap.airline_id
INNER JOIN airport_geo ag ON a.base_airport = ag.airport_id -- Langsung JOIN ke sumber data
WHERE
ag.country = 'FRANCE' -- Filter langsung
ORDER BY
ap.airplane_id;Justifikasi: Query perbaikan jauh lebih sederhana dan efisien karena:
-
Menghilangkan
WITHdan subquery, mengurangi kompleksitas dan overhead. -
Melakukan semua
JOINyang diperlukan dalam satu lingkup, memungkinkan optimizer untuk menemukan jalur eksekusi terbaik. -
Menghapus
DISTINCTyang tidak diperlukan. -
Hasilnya,
costlebih rendah danexecution timelebih cepat.