Performans Optimizasyonu

Index oluşturma, EXPLAIN ANALYZE ve sorgu optimizasyonu

Index (Dizin) Oluşturma

Temel Index Türleri

TürKullanımÖrnek
B-treeEşitlik, aralık sorguları=, <, >, BETWEEN
HashSadece eşitlik=
GiSTGeometrik, full-textPostGIS, FTS
GINArray, JSONB, full-text@>, ?
BRINBüyük sıralı tablolarZaman serisi

Index Oluşturma

-- Basit index
CREATE INDEX idx_users_email ON users(email);

-- Unique index
CREATE UNIQUE INDEX idx_users_email_unique ON users(email);

-- Composite index
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at DESC);

-- Partial index (filtrelenmiş)
CREATE INDEX idx_orders_pending ON orders(created_at) 
WHERE status = 'pending';

-- JSONB index
CREATE INDEX idx_data_tags ON documents USING GIN (data -> 'tags');

-- Concurrent (production için)
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
CONCURRENTLY seçeneği tabloyu kilitlemez ama daha uzun sürer.

EXPLAIN ANALYZE

Sorgunun nasıl çalıştığını analiz eder.

EXPLAIN ANALYZE
SELECT * FROM users WHERE email = 'test@example.com';
Index Scan using idx_users_email on users (cost=0.29..8.30 rows=1 width=42) Index Cond: (email = 'test@example.com'::text) Planning Time: 0.152 ms Execution Time: 0.089 ms

Önemli Metrikler

MetrikAçıklama
Seq ScanTüm tabloyu tarar (yavaş)
Index ScanIndex kullanır (hızlı)
Index Only ScanSadece index yeterli (en hızlı)
costTahmini maliyet
rowsTahmini satır sayısı
actual timeGerçek süre (ms)

Yavaş Sorguları Bulma

-- Yavaş sorgu logunu aç (postgresql.conf)
log_min_duration_statement = 1000  # 1 saniyeden uzun

-- pg_stat_statements extension
CREATE EXTENSION pg_stat_statements;

-- En yavaş sorgular
SELECT 
    query,
    calls,
    round(total_exec_time::numeric, 2) as total_ms,
    round(mean_exec_time::numeric, 2) as avg_ms
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

Connection Pooling

PgBouncer ile bağlantı havuzu oluşturun.

# PgBouncer kurulumu
sudo apt install pgbouncer -y

# /etc/pgbouncer/pgbouncer.ini
[databases]
myapp = host=127.0.0.1 port=5432 dbname=myapp

[pgbouncer]
listen_addr = *
listen_port = 6432
auth_type = md5
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 20