Performance Optimization: Optimasi Performa Query SQL 🚀
Halo SQL Explorers! 👋 Selamat datang di SQL Advanced!
Di level intermediate, kita udah belajar:
- JOIN yang kompleks
- Subquery dan fungsi agregat
- Views dan indexes
- Transaction management
- Database design
Sekarang kita bakal level up lagi dengan fokus ke PERFORMA! 🚀
Kenapa Performa Penting? 🤔
Di level basic dan intermediate, kita fokus ke “bikin query yang benar”. Sekarang kita bakal belajar “bikin query yang cepat”!
Bayangkan toko online kita udah sukses dan punya:
- 100,000+ pelanggan
- 50,000+ produk
- 1,000,000+ order
Query yang tadinya cepet bisa jadi lambat banget! 😱
Database yang Kita Pake 📊
Kita tetep pake database toko online, tapi dengan data yang lebih banyak:
-- Generate data dummy yang banyak
INSERT INTO customers (nama, email, kota)
SELECT
CONCAT('Customer', n),
CONCAT('customer', n, '@email.com'),
ELT(1 + MOD(n, 5), 'Jakarta', 'Bandung', 'Surabaya', 'Medan', 'Makassar')
FROM (
SELECT a.N + b.N * 10 + c.N * 100 + d.N * 1000 AS n
FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) a,
(SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) b,
(SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) c,
(SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) d
) numbers
WHERE n <= 100000;
Analisis Query Performance 📊
1. Pake EXPLAIN
EXPLAIN itu tool buat liat gimana database ngejalanin query:
-- Query yang mau dianalisis
EXPLAIN SELECT
c.nama AS customer,
COUNT(DISTINCT o.id) AS total_order,
SUM(oi.quantity * oi.price) AS total_belanja
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
LEFT JOIN order_items oi ON o.id = oi.order_id
WHERE c.kota = 'Jakarta'
GROUP BY c.id, c.nama;
-- Hasilnya:
+----+-------------+-------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | c | NULL | ALL | NULL | NULL | NULL | NULL | 100000 | 20.00 | Using where |
| 1 | SIMPLE | o | NULL | ref | customer_id | cust_id | 4 | c.id | 5 | 100.00 | NULL |
| 1 | SIMPLE | oi | NULL | ref | order_id | ord_id | 4 | o.id | 2 | 100.00 | NULL |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
2. Optimasi dengan Index
Index itu kayak “daftar isi” buat database:
-- Bikin index buat kolom yang sering dicari
CREATE INDEX idx_customer_city ON customers(kota);
CREATE INDEX idx_order_date ON orders(tanggal);
-- Query jadi lebih cepet!
EXPLAIN SELECT
c.nama AS customer,
COUNT(DISTINCT o.id) AS total_order
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE c.kota = 'Jakarta'
GROUP BY c.id, c.nama;
3. Rewrite Query yang Lambat
Kadang perlu tulis ulang query biar lebih cepet:
-- Query yang lambat
SELECT p.nama,
p.harga,
(SELECT AVG(harga) FROM products) as rata_rata_global,
(SELECT AVG(harga) FROM products WHERE category_id = p.category_id) as rata_rata_kategori
FROM products p;
-- Query yang lebih cepet
SELECT
p.nama,
p.harga,
avg1.rata_rata_global,
avg2.rata_rata_kategori
FROM products p
CROSS JOIN (
SELECT AVG(harga) as rata_rata_global
FROM products
) avg1
JOIN (
SELECT category_id, AVG(harga) as rata_rata_kategori
FROM products
GROUP BY category_id
) avg2 ON p.category_id = avg2.category_id;
Tips Optimasi Query 💡
**Hindari SELECT * **
-- Jangan gini SELECT * FROM products; -- Mending gini SELECT id, nama, harga FROM products;Pake Index dengan Tepat
- Index bikin SELECT cepet
- Tapi bikin INSERT/UPDATE lambat
- Jangan kebanyakan index
Batasi Jumlah Rows
-- Pake LIMIT SELECT * FROM orders ORDER BY tanggal DESC LIMIT 100;Hindari Subquery yang Berat
- Subquery dijalanin berkali-kali
- Lebih baik pake JOIN
- Atau simpan hasil di temporary table
Debugging Query yang Lambat 🔍
- Cek Execution Time
-- MySQL
SET profiling = 1;
SELECT ...your query...;
SHOW PROFILES;
-- PostgreSQL
EXPLAIN ANALYZE SELECT ...your query...;
- Identifikasi Bottleneck
- Tabel yang terlalu besar?
- Index yang kurang?
- JOIN yang kebanyakan?
- Subquery yang berat?
- Monitor Resource Usage
SHOW PROCESSLIST;
SHOW ENGINE INNODB STATUS;
Latihan Optimasi 🎯
- Optimasi Query Total Penjualan
-- Before optimization
SELECT
DATE(o.tanggal) as tanggal,
SUM(oi.quantity * oi.price) as total
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
WHERE o.tanggal >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DATE(o.tanggal);
-- After optimization
SELECT
DATE(o.tanggal) as tanggal,
SUM(oi.quantity * oi.price) as total
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
WHERE o.tanggal >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DATE(o.tanggal)
ORDER BY tanggal DESC;
- Optimasi Search Customer
-- Before optimization
SELECT *
FROM customers
WHERE nama LIKE '%budi%' OR email LIKE '%budi%';
-- After optimization
CREATE FULLTEXT INDEX idx_customer_search
ON customers(nama, email);
SELECT *
FROM customers
WHERE MATCH(nama, email) AGAINST('budi' IN BOOLEAN MODE);
Preview Materi Selanjutnya 🎯
Di materi Complex Queries nanti, kita bakal belajar:
- Common Table Expressions (CTE)
- Recursive queries
- Dynamic SQL
- Dan masih banyak lagi! 🚀