0%

SQL Veritabanı Optimizasyonu

Veritabanı sorgularını optimize etmek için temel ipuçları ve stratejiler.

📅
👤CodeBros
⏱️5 dakikada okunur
SQLVeritabanıOptimizasyon
SQL Veritabanı Optimizasyonu - Blog yazısı öne çıkan görseli

SQL Veritabanı Optimizasyonu

Veritabanı performansı, modern web uygulamalarının başarısında kritik bir rol oynar. Bu yazıda, SQL sorgularınızı optimize etmek için temel stratejileri inceleyeceğiz.

Neden SQL Optimizasyonu Önemli?

  • Performans: Hızlı sorgu sonuçları
  • Ölçeklenebilirlik: Büyük veri setlerinde verimlilik
  • Kaynak Kullanımı: CPU ve bellek tasarrufu
  • Kullanıcı Deneyimi: Daha hızlı uygulama

1. İndeks Stratejileri

Primary Key İndeksleri

-- Otomatik olarak oluşturulan primary key indeksi
CREATE TABLE users (
    id INT PRIMARY KEY,
    email VARCHAR(255) UNIQUE,
    name VARCHAR(100)
);

Composite İndeksler

-- Birden fazla kolonu kapsayan indeks
CREATE INDEX idx_user_email_status 
ON users(email, status);

-- Sorgu optimizasyonu
SELECT * FROM users 
WHERE email = 'test@example.com' 
AND status = 'active';

İndeks Kullanım İpuçları:

  • WHERE clause'da sık kullanılan kolonlar
  • JOIN işlemlerinde kullanılan foreign key'ler
  • ORDER BY ve GROUP BY işlemlerinde kullanılan kolonlar

2. Sorgu Optimizasyonu

N+1 Problem Çözümü

-- Yanlış yaklaşım (N+1 problem)
SELECT * FROM posts; -- 1 sorgu
-- Her post için ayrı sorgu (N sorgu)
SELECT * FROM comments WHERE post_id = 1;
SELECT * FROM comments WHERE post_id = 2;
-- ... N kez tekrar

-- Doğru yaklaşım (JOIN kullanımı)
SELECT p.*, c.* 
FROM posts p
LEFT JOIN comments c ON p.id = c.post_id
ORDER BY p.id, c.created_at;

Subquery vs JOIN

-- Yavaş subquery
SELECT * FROM products 
WHERE category_id IN (
    SELECT id FROM categories 
    WHERE name = 'Electronics'
);

-- Hızlı JOIN
SELECT p.* 
FROM products p
INNER JOIN categories c ON p.category_id = c.id
WHERE c.name = 'Electronics';

3. WHERE Clause Optimizasyonu

İndeks Kullanımını Engelleyen Durumlar

-- Yanlış: Fonksiyon kullanımı
SELECT * FROM users 
WHERE UPPER(email) = 'TEST@EXAMPLE.COM';

-- Doğru: Direkt karşılaştırma
SELECT * FROM users 
WHERE email = 'test@example.com';

-- Yanlış: Leading wildcard
SELECT * FROM users 
WHERE email LIKE '%@gmail.com';

-- Doğru: Trailing wildcard
SELECT * FROM users 
WHERE email LIKE 'john%';

Veri Tipi Uyumluluğu

-- Yanlış: Veri tipi uyumsuzluğu
SELECT * FROM users 
WHERE id = '123'; -- id INT, '123' VARCHAR

-- Doğru: Uyumlu veri tipi
SELECT * FROM users 
WHERE id = 123;

4. LIMIT ve OFFSET Optimizasyonu

Büyük OFFSET Problemı

-- Yavaş: Büyük offset değeri
SELECT * FROM posts 
ORDER BY created_at DESC 
LIMIT 10 OFFSET 1000000;

-- Hızlı: Cursor-based pagination
SELECT * FROM posts 
WHERE created_at < '2025-01-01 00:00:00'
ORDER BY created_at DESC 
LIMIT 10;

5. Veritabanı Tasarım Optimizasyonu

Normalizasyon vs Denormalizasyon

-- Normalize edilmiş yapı
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

CREATE TABLE user_profiles (
    user_id INT,
    bio TEXT,
    avatar VARCHAR(255),
    FOREIGN KEY (user_id) REFERENCES users(id)
);

-- Denormalize edilmiş yapı (performans için)
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    bio TEXT,
    avatar VARCHAR(255)
);

Veri Tipi Seçimi

-- Bellek tasarrufu için uygun veri tipleri
CREATE TABLE products (
    id INT UNSIGNED,           -- Negatif değer gerekmiyorsa
    price DECIMAL(10,2),       -- Para birimi için
    status ENUM('active', 'inactive'), -- Sınırlı seçenekler
    created_at TIMESTAMP       -- Otomatik güncelleme
);

6. Sorgu Analizi Araçları

EXPLAIN Kullanımı

-- Sorgu execution plan'ını görme
EXPLAIN SELECT * FROM users 
WHERE email = 'test@example.com';

-- Detaylı analiz
EXPLAIN ANALYZE SELECT u.*, p.* 
FROM users u 
LEFT JOIN posts p ON u.id = p.user_id 
WHERE u.created_at > '2025-01-01';

Slow Query Log

-- Slow query log'u aktif etme
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2; -- 2 saniyeden uzun sorgular

-- Slow query'leri görme
SELECT * FROM mysql.slow_log 
WHERE start_time > NOW() - INTERVAL 1 DAY;

7. Caching Stratejileri

Query Cache

-- Query cache durumunu kontrol etme
SHOW VARIABLES LIKE 'query_cache%';

-- Cache'lenebilir sorgu yazma
SELECT SQL_CACHE * FROM products 
WHERE status = 'active';

-- Cache'lenmemesi gereken sorgu
SELECT SQL_NO_CACHE * FROM products 
WHERE created_at > NOW() - INTERVAL 1 HOUR;

Application Level Caching

# Redis ile caching örneği
import redis
import json

r = redis.Redis(host='localhost', port=6379, db=0)

def get_user_posts(user_id):
    cache_key = f"user_posts:{user_id}"
    cached_data = r.get(cache_key)
    
    if cached_data:
        return json.loads(cached_data)
    
    # Veritabanından veri çek
    posts = execute_query(f"SELECT * FROM posts WHERE user_id = {user_id}")
    
    # Cache'le (1 saat)
    r.setex(cache_key, 3600, json.dumps(posts))
    return posts

8. Monitoring ve Bakım

Performans Metrikleri

-- Aktif bağlantıları görme
SHOW PROCESSLIST;

-- Tablo boyutlarını kontrol etme
SELECT 
    table_name,
    round(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)'
FROM information_schema.tables 
WHERE table_schema = 'your_database'
ORDER BY (data_length + index_length) DESC;

-- İndeks kullanım istatistikleri
SELECT * FROM sys.schema_index_statistics 
WHERE table_schema = 'your_database';

Düzenli Bakım

-- Tablo optimizasyonu
OPTIMIZE TABLE your_table;

-- İndeks yeniden oluşturma
ALTER TABLE your_table DROP INDEX idx_name;
ALTER TABLE your_table ADD INDEX idx_name (column_name);

-- İstatistik güncelleme
ANALYZE TABLE your_table;

9. Pratik Öneriler

DOs (Yapılması Gerekenler):

  • İndeks kullanın - Sık sorguladığınız kolonlar için
  • LIMIT kullanın - Büyük sonuç setlerinde
  • WHERE clause optimize edin - Erken filtreleme
  • Veri tiplerini optimize edin - Uygun boyutlar
  • Regular monitoring - Performans takibi

DON'Ts (Yapılmaması Gerekenler):

  • SELECT * kullanmayın - Sadece gerekli kolonları seçin
  • Gereksiz JOIN'ler - Sadece gerekli tabloları birleştirin
  • Fonksiyon kullanmayın WHERE'de - İndeks kullanımını engeller
  • Çok fazla indeks - INSERT/UPDATE performansını düşürür

10. Sonuç

SQL optimizasyonu sürekli bir süreçtir. Önemli olan:

  1. Measure First - Önce ölçün, sonra optimize edin
  2. Index Wisely - Doğru indeksleme stratejisi
  3. Query Smart - Akıllı sorgu yazımı
  4. Monitor Constantly - Sürekli izleme

Bu stratejileri uygulayarak veritabanı performansınızı önemli ölçüde artırabilirsiniz.

Kaynaklar


Bu yazı SQL optimizasyonu konusunda temel bilgiler sunmaktadır. Veritabanı türüne göre spesifik optimizasyonlar farklılık gösterebilir.

K
CodeBros
CodeBros - Profesyonel Yazılım Geliştirme Şirketi
Paylaş:
WhatsApp
WhatsApp