1. Eager Loading Kullanımı ile 'N+1 Query' Hatasını Engelleme
N+1 Query hatası, bir nesnenin ilişkili olduğu diğer nesneleri veritabanından her seferinde ayrı ayrı sorgulamak zorunda kaldığınızda ortaya çıkar. Bu sorunla başa çıkmanın en yaygın ve etkili yolu eager loading kullanmaktır. Rails'de `includes` veya `joins` yöntemleri ile ilişkili verileri önceden yüklemek, her bir ilişki için ekstra sorgu yapılmasını engeller.
# N+1 Query Hatası
posts = Post.all
posts.each do |post|
puts post.comments.count
end
# Eager Loading ile Optimizasyon
posts = Post.includes(:comments).all
posts.each do |post|
puts post.comments.count
end
Bu şekilde, `comments` ilişkisini her bir `Post` nesnesi için tek tek sorgulamak yerine, tüm yorumlar önceden yüklenir ve yalnızca bir sorgu yapılır.
2. `select` ile İhtiyaç Duyduğunuz Alanları Belirtme
Veritabanı sorgularınızda yalnızca gerekli alanları seçmek, gereksiz veri yüklemesini engeller ve sorgu performansını artırır. Rails'de `select` methodu ile sadece ihtiyacınız olan sütunları alabilirsiniz. Bu, özellikle büyük tablolarda çok faydalıdır.
# Gereksiz Verilerden Kaçınma
Post.select(:id, :title).includes(:comments).each do |post|
puts post.title
end
Bu şekilde, yalnızca gerekli alanlar sorgulanır ve gereksiz veri yüklemesi engellenmiş olur.
3. `joins` ile Doğrudan İlişkili Verileri Çekme
Eğer ilişkili verilere yalnızca veritabanında işlem yaparak erişmeniz gerekiyorsa, joins metodunu kullanmak daha verimli olabilir. `includes` ilişkili verileri önceden yüklerken, `joins` sorgularda doğrudan ilişkiyi kullanarak veri almanızı sağlar.
# Joins ile İlişkili Verilere Erişme
Post.joins(:comments).where("comments.created_at > ?", 1.week.ago).each do |post|
puts post.title
end
4. `counter_cache` ile Sayım İşlemlerini Optimize Etme
Veritabanındaki bazı işlemler, örneğin bir nesnenin ilişkili verilerinin sayısını almak, sıkça yapılabilir. Bu tür sayımların performansını artırmak için, Rails'de counter_cache özelliğini kullanabilirsiniz. Bu özellik, ilişkili verilerin sayısını otomatik olarak tutar, böylece her seferinde `count` sorgusu çalıştırmanıza gerek kalmaz.
# Counter Cache Özelliği
class Post < ApplicationRecord
has_many :comments, counter_cache: true
end
5. Batch İşlemleri ile Sorgu Sayısını Azaltma
Veritabanı sorguları her zaman ağ üzerinden yapılır, bu nedenle çok fazla sorgu yapıldığında performans ciddi şekilde düşebilir. Batch işlemleri, veritabanı üzerinde aynı türdeki verileri topluca işleyerek bu sorunla başa çıkmanın etkili bir yoludur. Rails'deki `find_in_batches` veya `in_batches` metodu ile büyük veri setlerini parçalara ayırarak işlem yapabilirsiniz.
# Batch işlemi ile veri işleme
Post.find_in_batches(batch_size: 100) do |posts|
posts.each do |post|
puts post.title
end
end
6. Veritabanı İndeksleri Kullanma
İndeksler, veritabanınızda veri arama ve sıralama işlemlerini hızlandıran yapılar olup performans üzerinde doğrudan etki yapar. İlişkili verilere sıkça erişiliyorsa, bu alanlarda indeks kullanmak işlemleri çok daha hızlı hale getirebilir.
# Veritabanı Kolonunda İndeks Oluşturma
add_index :comments, :post_id
7. Sorgu Optimizasyonu İçin `explain` Kullanma
Rails'deki `explain` komutuyla, sorguların nasıl çalıştığını ve hangi indekslerin kullanıldığını görebilirsiniz. Bu sayede, veritabanı sorgularının ne kadar verimli çalıştığını anlamanızı sağlar.
# Sorgu açıklamasını görmek
Post.where("created_at > ?", 1.week.ago).explain
8. Yavaş Sorguları İzleme ve Güncelleme
Veritabanınızda yavaş çalışan sorguları tespit etmek, performans problemlerini çözmenin önemli bir adımıdır. Rails, yavaş sorguları log dosyalarında kaydeder. Bu logları inceleyerek hangi sorguların yavaş çalıştığını tespit edebilir ve optimizasyon yapabilirsiniz.
9. N+1 Query Hatasını Tespit Etmek İçin `bullet` Gem'i Kullanma
Rails uygulamanızda N+1 Query hatalarını tespit etmek ve çözmek için bullet gem'ini kullanabilirsiniz. Bu gem, gereksiz sorguları yakalayarak geliştiriciyi uyarır.
# Bullet Gem ile Uyarı Almak
gem 'bullet'
10. Arka Plan İşlemeleri Kullanma
Uzun süren veri işleme süreçlerini background jobs ile arka planda çalıştırarak, uygulamanızın tepki hızını artırabilirsiniz. Bu sayede, kullanıcı deneyimi bozulmadan uzun süren işlemleri yönetebilirsiniz.
# Arka planda çalışan bir job
class ProcessDataJob < ApplicationJob
queue_as :default
def perform(*args)
# Veri işleme işlemleri
end
end