PHP ve MYSQL ile rastgele kayıt çektirmenin yolları

Standard

Aslında herkesin ihtiyacı olan ve sürekli kullanılan bu işlem için bir çoğumuz SQL içersinde ORDER BY RAND() diyerek bu işlemi hallediyor. Ancak veritabanındaki kayıtlar büyüdükçe bu şekilde yapmanız işlemi zorlaştıracak, sayfanızı yavaşlatacaktır.

Geçtiğimiz hafta arkadaşımın çalıştığı projede böyle bir durum gerçekleşti. Bende az önce belirtmiş olduğum yönteme alternetif neler var onu araştırmak paylaşmak istedim.

Daha uzatmadan yavaş yavaş yöntemleri ele alalım.

Çözüm 1 (SQL ile)

SELECT * FROM `table` ORDER BY RAND() LIMIT 0,1;

Tabi bu en kolay, pratik ama en yavaş yöntemdir aslında. Bu kadar yavaş olma nedeni MySQL, sonuçta dönen tüm satırlar için geçici bir tablo oluşturur ve bunların her biri için rasgele sıralama endeksi atar olmasıdır. Daha sonra sonuçlar sıralanır ve iade edilir.

Çözüm 2 (PHP)

$range_result = mysql_query("SELECT MAX(`id`) AS max_id , MIN(`id`) AS min_id FROM `table` ");
$range_row = mysql_fetch_object($range_result); 
$random = <strong>mt_rand</strong>( $range_row-&gt;min_id , $range_row-&gt;max_id );
$result = mysql_query( " SELECT * FROM `table` WHERE `id` &gt;= $random LIMIT 0,1 ");

Bu yöntem PK sahip tablolar ile sınırlıdır.

Gördüğünüz gibi aralık belirledik ve MySQL LIMIT ifadesini kullanmakdık. LIMIT iki argüman kabul eder.İlk argüman dönmek için ilk satırın offset belirtir ve ikinci dönmek için satır sayısını belirtir.
İlk satırın ofset 0 (değil 1) ‘dir.

Çözüm 3 (PHP):

$offset_result = mysql_query( " SELECT FLOOR(RAND() * COUNT(*)) AS `offset` FROM `table` ");
$offset_row = mysql_fetch_object( $offset_result ); 
$offset = $offset_row->offset;
$result = mysql_query( " SELECT * FROM `table` LIMIT $offset, 1 " );

Bu işlemi mysql 4.1 ve sonraki sürümlerinde subquery ile aşağıdaki şekilde yapabilirsiniz;

Çözüm 4 (SQL):

SELECT * FROM `table` WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` ) ORDER BY id LIMIT 1;

Bu 4 yönteme baktığımızda sonuçlar;

  • En yavaş yöntem 1. Kullanıcının yaptığı işlem süresine %100 diyelim.
  • Çözüm 2 – 79%
  • Çözüm 3 – 13%
  • Çözüm 4 – 16%

Bu durumda en performanslı olan yönteme 3. diyebiliriz.

Tabi eğer aynı tabloda kayıt yedeklerini tutuyorsanız, silinen kayıtları vs. tutuyorsanız o zaman iş değişecektir..

Bu konuda yazılmış kapsamlı başka bir makale paylaşmak isterim bende araştırırken karşılaştım; http://jan.kneschke.de/projects/mysql/order-by-rand/

Daha güzel veya pratik önerileriniz varsa onları da ekleyebiliriz.

Herkese iyi çalışmalar dilerim..

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir