MySQL veritabanında bir tablodan rastgele sırada kayıt seçmek için birkaç yol


Açık kaynak bir RDBMS (Relational DataBase Management System) olan MySQL’de bulduğum tek kusur adında aslında. Açık kaynak olunca My yerine Our demek daha iyi olurdu diye düşünüyorum.

Şu günlerde yazmakta olduğum çevrim içi sınav sistemi için bir problemle karşılaştım…

Sıkıntım şu idi:

Sınavda soruların ve sorulara ait cevapların rastgele sırada gelmesini istiyordum. Sınava giren kişi her defasında aynı soru ile başlamasın ve her defasında soruya ait cevap seçenekleri aynı sırada gelmesin istiyordum. Ama bunu PHP tarafında kodlama ile çözmek yerine veritabanından bu halde gelmesini istemekteydim. Bu hem performans açısından da büyük önem arzetmekteydi.

Bunun için internette kısa süren bir arama yaptım. RAND() fonksiyonundan bahsediliyordu. Bu fonksiyon 0 ile 1 arasında ondalıklı bir sayı üretir. Bu fonksiyonu kayıtları seçerken kullanmak için çok basit bir örnek aşağıda mevcut:

SELECT * FROM Sorular WHERE onay = 1 AND seviye = 1 ORDER BY RAND()

Anlayacağınız gibi sorgumuz, Sorular tablosunda, onaylı ve birinci seviyede olan tüm kayıtları tüm alanlarıyla birlikte rastgele olarak seçmektedir.

MySQL resmi sitesinde diyor ki:

Ey Türk Gençliği!

Birinci vazifen ORDER BY RAND() ifadesinden sonra LIMIT ifadesini kullanmaktır. Yoksa sorgu çalışırken defalarca aynı işlemi yaptırmış olursun. İşi uzatırsın.  Onun yerine şöyle yap:

SELECT * FROM Sorular WHERE onay = 1 AND seviye = 1 ORDER BY RAND() LIMIT 50

Bu sayede çok daha çabuk bir sonuç dönecektir.

Çok kolay ve çok pratik gibi görünse de bunu performans açısından bir irdelemek lazım. Zira belki birkaç yüz kayıt için sorun çıkmayabilir. Ama kayıt sayısı onbinlerle ifade edilmeye başladığında sıkıntı olması muhtemel. Çok fazla kaydın tutulduğu tabloda bu sorgu çalıştırılırsa tüm tabloyu önce tarayacak sonrada rastgele bir şekilde sıralayacaktır.

Belki alt sorgu kullanmak daha iyi bir yaklaşım olabilir. Tüm tabloyu taradıktan sonra alıp getirmektense

SELECT * FROM Sorular WHERE onay = 1 AND seviye = 1 AND id IN( SELECT id FROM Sorular ORDER BY RAND() LIMIT 50)

şeklinde de sorgu yazılabilir. Bunun avantajı tüm tablonun alanlarını getirmekle birlikte taradığı sadece id alanının tamamını tarar. Bu sayede sorgu biraz daha çabuk cevaplanır. Hele ki geniş bir tablonuz varsa…

NOT: Seçilecek sütun isimleri yerine * yazdım. Ama siz yazmayın. Sadece ihtiyacınız olan sütun isimlerini yazın. Üşenmeyin.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Connecting to %s