Index (Dizin) Oluşturma
Temel Index Türleri
| Tür | Kullanım | Örnek |
|---|---|---|
| B-tree | Eşitlik, aralık sorguları | =, <, >, BETWEEN |
| Hash | Sadece eşitlik | = |
| GiST | Geometrik, full-text | PostGIS, FTS |
| GIN | Array, JSONB, full-text | @>, ? |
| BRIN | Büyük sıralı tablolar | Zaman 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
| Metrik | Açıklama |
|---|---|
| Seq Scan | Tüm tabloyu tarar (yavaş) |
| Index Scan | Index kullanır (hızlı) |
| Index Only Scan | Sadece index yeterli (en hızlı) |
| cost | Tahmini maliyet |
| rows | Tahmini satır sayısı |
| actual time | Gerç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