Belajar Performance Test Engineer - Database Performance Engineering
Episode 24 of 28

Belajar Performance Test Engineer - Database Performance Engineering

Deep dive database performance: query profiling dengan EXPLAIN ANALYZE, indexing strategies (B-tree, hash, partial), connection pooling optimization, database tuning parameters, dan scaling strategies (read replicas, sharding).

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 23 kita memahami AI workload performance, kini saatnya membahas area yang menjadi akar masalah performa paling sering: database performance. Sebagian besar bottleneck performance testing muncul di database — query yang lambat, index yang tidak ada, connection pool yang habis, atau locking yang berlebihan. Database performance engineering adalah skill yang membedakan performance engineer biasa dari yang benar-benar efektif.

Episode ini membawa kalian deep dive ke database profiling, indexing strategies, dan tuning parameters yang secara langsung mempengaruhi performa aplikasi.

Query Profiling

EXPLAIN ANALYZE

EXPLAIN ANALYZE adalah tool paling powerful untuk memahami bagaimana database mengeksekusi query:

sql
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT o.*, u.name
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE o.status = 'pending'
AND o.created_at > '2026-01-01'
ORDER BY o.created_at DESC
LIMIT 100;

Membaca Execution Plan

Node TypeArti
Seq ScanFull table scan — lambat untuk tabel besar
Index ScanMenggunakan index — cepat
Bitmap Index ScanMultiple index lookups
Hash JoinJoin menggunakan hash — cepat untuk large datasets
Nested LoopJoin menggunakan loop — lambat untuk large datasets

Identifikasi Masalah

plaintext
Seq Scan on orders  (cost=0..1000 rows=500000)
→ Tidak ada index untuk WHERE status = 'pending'
→ Buat index: CREATE INDEX idx_orders_status ON orders(status)
 
Sort  (cost=5000..5200 rows=100)
→ Sorting tidak menggunakan index
→ Buat composite index yang include ORDER BY column

Indexing Strategies

B-Tree Index

B-tree adalah index default untuk大多数 database — cocok untuk equality checks dan range queries.

sql
-- B-tree index untuk equality dan range
CREATE INDEX idx_orders_user_created
ON orders (user_id, created_at DESC);
 
-- Query yang menggunakan index ini
SELECT * FROM orders WHERE user_id = 123 AND created_at > '2026-01-01';

Hash Index

Hash index sangat cepat untuk equality checks tetapi tidak mendukung range queries:

sql
-- Hash index untuk equality saja
CREATE INDEX idx_users_email_hash
ON users USING hash (email);

Partial Index

Partial index mengindex hanya subset baris — mengurangi ukuran index dan meningkatkan performa:

sql
-- Index hanya untuk orders pending (sedikit dari total)
CREATE INDEX idx_orders_pending
ON orders (created_at DESC)
WHERE status = 'pending';

Covering Index

Covering index mencakup semua kolom yang dibutuhkan query — mengeliminasi kebutuhan untuk mengakses tabel utama:

sql
-- Covering index: query tidak perlu akses tabel
CREATE INDEX idx_orders_covering
ON orders (user_id, created_at DESC)
INCLUDE (status, total);
 
-- Query ini dijawab sepenuhnya dari index
SELECT status, total FROM orders
WHERE user_id = 123
ORDER BY created_at DESC;

Index Anti-Patterns

Anti-PatternMasalahSolusi
Too many indexesWrite performance turunHapus index yang tidak dipakai
Wrong column orderIndex tidak efektifKolom dengan selectivity tinggi duluan
No composite indexBanyak single-column indexesComposite index untuk query patterns
Unused indexesOverhead tanpa manfaatCek pg_stat_user_indexes

Connection Pool Optimization

Pool Size Calculation

plaintext
Pool Size ≈ (CPU cores × 2) + effective_spindle_count
 
Untuk SSD: (CPU cores × 2) + 1
Contoh: 8 cores → pool size ≈ 17

Connection Pool Monitoring

sql
-- PostgreSQL: monitor connection usage
SELECT
  state,
  count(*),
  max(now() - state_change) as max_duration
FROM pg_stat_activity
GROUP BY state;
 
-- Connection pool wait time
SELECT
  datname,
  numbackends,
  numbackends * 100.0 / (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as pct_used
FROM pg_stat_database;

PgBouncer

PgBouncer adalah connection pooler yang mengurangi overhead koneksi PostgreSQL:

ini
# pgbouncer.ini
[databases]
mydb = host=localhost port=5432 dbname=mydb
 
[pgbouncer]
pool_mode = transaction  # Pool per transaction, bukan per session
max_client_conn = 1000
default_pool_size = 20

Database Tuning Parameters

PostgreSQL Key Parameters

sql
-- Memory
shared_buffers = '4GB'           -- 25% of RAM
effective_cache_size = '12GB'    -- 75% of RAM
work_mem = '256MB'               -- Per-operation memory
 
-- Query Planning
random_page_cost = 1.1           -- SSD (default 4.0 untuk HDD)
effective_io_concurrency = 200   -- SSD
 
-- WAL
wal_buffers = '64MB'
checkpoint_completion_target = 0.9

Monitoring Tuning Impact

bash
# Reload configuration tanpa restart
SELECT pg_reload_conf();
 
-- Cek parameter saat ini
SHOW shared_buffers;
SHOW effective_cache_size;

Scaling Strategies

Read Replicas

Read replicas menambah throughput untuk read-heavy workloads:

sql
-- Arahkan read queries ke replica
-- Application routing
SELECT * FROM products WHERE id = 123;  -- ke replica
UPDATE products SET price = 29.99 WHERE id = 123;  -- ke primary

Sharding

Sharding membagi database menjadi banyak shards berdasarkan shard key:

sql
-- Shard by user_id
-- Shard 0: user_id % 4 == 0
-- Shard 1: user_id % 4 == 1
-- Shard 2: user_id % 4 == 2
-- Shard 3: user_id % 4 == 3

Connection Pooling at Scale

yaml
# PgBouncer pool per shard
shard_0: host=pg-0 port=5432 dbname=mydb
shard_1: host=pg-1 port=5432 dbname=mydb
shard_2: host=pg-2 port=5432 dbname=mydb
shard_3: host=pg-3 port=5432 dbname=mydb

Penutup

Di episode 24 ini kalian telah memahami database performance engineering:

  • Query profiling: EXPLAIN ANALYZE untuk memahami execution plan.
  • Indexing: B-tree, hash, partial, dan covering indexes.
  • Connection pooling: PgBouncer, pool size calculation.
  • Tuning parameters: PostgreSQL key parameters untuk performance.
  • Scaling: read replicas dan sharding strategies.

Di episode 25 selanjutnya, kita akan membahas Performance Architecture Review — bagaimana melakukan review arsitektur dari perspektif performa dan scalability. Siapkan architecture diagram kalian!

Belajar Performance Test Engineer - Database Performance Engineering | Belajar Performance Test Engineer