Laravel Benchmark Sınıfı

585

Laravel ile ilgili yeni başlayanların en sık yaptığı hatalardan bir tanesi de, örneklerden yola çıkarak birçok veritabanı sorgusunu all() metoduyla yapmasıdır. Eğer veritabanınızda birkaç yüz satırlık bir veriyle işlem yapıyorsanız başta bunun bir dezavantajını görmeyebilirsiniz ama verileriniz -elbette sakladığınız veririnin büyüklüğüne ve sunucunuzun performansına göre değişebilir- onbinleri/yüzbinleri bulduğu zaman, kullanıcılarınızın yoğunluğuna göre bu sorgular performans açısından oldukça can sıkıcı bir hal alabilir.

Böyle problemlerle karşılaşmamak için veritabanı sorgularınızı mutlaka optimize etmeniz gerekmekte. Bunun için birkaç yöntem var. Harici paketleri (Laravel Debugbar bunlardan en popüleri olabilir) projenize dahil ederek, yaptığınız sorgunun kaç saniyede (ya da milisaniyede) gerçekleştiğini, bu sorguyla birlikte ne kadar bellek kullanıldığını görebilirsiniz.

Bu tür paketlerin yanısıra Laravel'e 9. versiyondan itibaren dahili gelen sınıflarından biri olan Benchmark'ı kullanabilirsiniz. Debugbar kadar ayrıntılı bir çıktı vermese de genel olarak sorgunuzun kaç milisaniyede gerçekleştiğini ölçebilir ya da iterasyon sayısı belirleyip çoklu sorguları tek seferde inceleyebilirsiniz. Örnek kullanım ise aşağıdaki gibi olabilir:

<?php
 
use App\Models\User;
use App\Models\Post;
use Illuminate\Support\Benchmark;
 
Benchmark::dd(fn () => User::find(1)); // 0.1 ms
 
Benchmark::dd([
    'Scenario 1' => fn () => User::count(), // 0.5 ms
    'Scenario 2' => fn () => User::all()->count(), // 20.0 ms
]);

Benchmark::dd([
    'Scenario Count' => fn () => Post::count(), // 0.5 ms
    'Scenario All with Count' => fn () => Post::all()->count(), // 20.0 ms
]);

Benchmark::dd(fn () => User::count(), iterations: 10); // 0.5 ms

Çok basit bir şekilde Controller metodunuza (ya da blade sayfanıza) ekleyeceğiniz bir satırlık kod ile yapacağınız sorgunun ne kadar sürede tamamladığını ekrana Dump&Die (dd()) fonsiyonu ile basabilirsiniz. 

Bu şekilde basit bir saydırma işlemi için bir tablonun tamamının bir koleksiyona alınıp saydırılması yerine direkt olarak tablonun satırlarının saydırılmasının, bir ilişkisi olan tabloyu with metodu ile çağırmanın ya da sadece işlem yapacağınız sütunları select ile seçerek ne kadar ciddi bir süreyi kısattığınızı görebilirsiniz.

Yaklaşık 200.000 satırlık tabloda yaptığım bazı testlerin sonuçlarının aşağıya ekliyorum.

array:7 [▼ // vendor/laravel/framework/src/Illuminate/Support/Benchmark.php:48
  "Scenario Count" => "74.262ms"
  "Scenario All with Count" => "3,031.070ms"
  "Scenario Pluck 5 Column" => "1,635.696ms"
  "Scenario Pluck 5 Column with Where" => "1,822.588ms"
  "Scenario Select 5 Column" => "0.072ms"
  "Scenario Select 5 Column with Where" => "0.062ms"
  "Scenario Select 5 Column with Where with 3 Iteration" => "0.044ms"
]

Bunları düşünerek mutlaka projenizi gerçekçi senaryolarla gerekirse 100 binlerce satırla Seed ederek performans testlerini yapmayı unutmayın. Bu şekilde hem sunucunuzu performans darboğazından kurtarırsınız hem de ziyaretçilerinize daha bir deneyim sunabilirsiniz.