• 0216 210 0483
  • Küçükbakkalköy Mah. Çandarlı Sk No :7 Ekşioğlu Plaza Kat:3 Daire:18 Ataşehir/İSTANBUL
Database Performance Optimization: PostgreSQL Production Tips

Database Performance Optimization: PostgreSQL Production Tips

Database Performance Optimization: PostgreSQL Production Tips

Database slow query nedeniyle application performance %70 düşebilir. PostgreSQL optimization tricks production'da fark yaratır.

1. Index Strategy

❌ Slow Query:

SELECT * FROM users WHERE email = '[email protected]';
-- Seq Scan: 500ms

✅ Indexed:

CREATE INDEX idx_users_email ON users(email);
-- Index Scan: 2ms

Advanced: Partial Index

CREATE INDEX idx_active_users ON users(email) 
WHERE status = 'active';
-- Smaller index, faster

2. Query Optimization

EXPLAIN ANALYZE kullan:

EXPLAIN ANALYZE
SELECT u.*, o.total 
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.created_at > NOW() - INTERVAL '30 days';

Execution plan'a bak:

  • Seq Scan → Index gerekli
  • Nested Loop → JOIN strategy problem
  • High cost → Optimize et

3. Connection Pooling

❌ Her request yeni connection:

// App connects directly
const client = new Client({
  host: 'db.example.com',
  port: 5432
});
// Max connections: 100, app crashed

✅ PgBouncer:

# pgbouncer.ini
[databases]
mydb = host=postgres port=5432 dbname=mydb

[pgbouncer]
pool_mode = transaction
max_client_conn = 10000
default_pool_size = 20

10,000 app connections → 20 DB connections. Connection reuse.

4. Vacuum & Analyze

PostgreSQL dead tuples birikir. Performance düşer.

-- Manual vacuum
VACUUM ANALYZE users;

-- Auto vacuum config
ALTER TABLE users SET (autovacuum_vacuum_scale_factor = 0.1);

-- Monitoring
SELECT schemaname, relname, n_dead_tup, n_live_tup
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;

5. Partitioning

Büyük tablolar (100M+ rows) partition et:

-- Range partitioning
CREATE TABLE orders (
  id BIGSERIAL,
  user_id INT,
  created_at TIMESTAMP
) PARTITION BY RANGE (created_at);

CREATE TABLE orders_2024_01 PARTITION OF orders
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');

CREATE TABLE orders_2024_02 PARTITION OF orders
FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');

Query sadece ilgili partition scan eder. Faster.

6. Replication & Load Balancing

Primary-Replica Setup:

  • Writes → Primary
  • Reads → Replicas (load balanced)
  • Async replication (low latency)
# postgresql.conf (primary)
wal_level = replica
max_wal_senders = 3

# recovery.conf (replica)
primary_conninfo = 'host=primary port=5432'
hot_standby = on

7. Monitoring Queries

Slow queries:

SELECT pid, now() - query_start as duration, query
FROM pg_stat_activity
WHERE state = 'active'
  AND now() - query_start > interval '5 seconds'
ORDER BY duration DESC;

Lock waits:

SELECT blocked_locks.pid,
       blocking_locks.pid AS blocking_pid,
       blocked_activity.query AS blocked_query
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity 
  ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks 
  ON blocking_locks.locktype = blocked_locks.locktype
WHERE NOT blocked_locks.granted;

8. Configuration Tuning

# postgresql.conf
shared_buffers = 4GB           # 25% of RAM
effective_cache_size = 12GB    # 75% of RAM
work_mem = 64MB
maintenance_work_mem = 512MB
max_connections = 200
random_page_cost = 1.1         # SSD
effective_io_concurrency = 200

Sonuç

Database optimization layered approach. Index, query, config, monitoring hepsi gerekli. Devups DB performance audit.