İyinet'e Hoşgeldiniz!

Türkiye'nin En Eski Webmaster Forum'una Hemen Kayıt Olun!

Kayıt Ol!

Rand ile alınan verilere alternatif var mı ?

OsmanAtabey

0
İyinet Üyesi
Katılım
26 Mart 2005
Mesajlar
922
Reaction score
4
PHP:
$sorgu = mysql_query("SELECT * FROM `tablo` ORDER BY RAND() limit 0,10");

mysql sorgusunda kullanılan rand() db büyüdükçe ve anlık girişler çoğaldıkça mysql hatalarına sebep oluyor.

Php 'de verileri for ile çekmeyi denedim fakat db büyüdükçe buda rand() 'dan farksız olacak gibime geliyor. Cache sistemine entegre etmeyi denedim fakat sorgu devamlı olarak çalışmaya devam ediyor.

Şu anda veritabanında 15 bin veri var. Bunu 100 bin yapmak istiyorum. mysql .cnf php.ini ve apache ayarlarında değişiklik yaparak düzgün hızlar sağladım fakat rand() bölümü için bir çözüm arıyorum.

Bu fonksiyon yerine başka bir alternatif varmıdır ?
 

yagmayok

1
İyinet Üyesi
Katılım
25 Ocak 2005
Mesajlar
7,131
Reaction score
89
En mantıklısı sadece random olarak alınan bölgeyi cachelemektir eğer bu sistemi uyguladıysanız ve belirttiğiniz gibi sorgu sürekli olarak gene çalışıyorsa bir yerde hata yapmışsınızdır. Bence bunun üzerinde durun.

Ama onun dışında yapılacak işlemler içinde birkaç düzenleme yapmak daha iyi bir yaklaşım olabilir.

Mesela:

PHP:
$sorgu = mysql_query("SELECT id,baslik FROM `tablo` ORDER BY RAND() limit 0,10");

yukarıdaki gibi tabloda sadece ihtiyaç duyulan bölgeleri almak.

Veya şu şekilde bir yol da izlenebilir. 10000 veriyi günde bir kaç kere (3-4 defa olabilir) bir kısmını başka bir tabloya istediğiniz kadar içerik olacak şekilde random olarak almasını sağlayabilirsiniz. Oradan da random olarak çektirirsiniz. Böylece daha az veri içinde random olarak çektirmiş olursunuz.

Aklıma başka bir yöntem gelmiyor.
 

Angelo

0
İyinet Üyesi
Katılım
13 Aralık 2004
Mesajlar
9,603
Reaction score
111
Konum
AZ
ID'lerde atlama yoksa, php de 10 tane random üret, WHERE id IN ('1','257','867')
gibi bir sorgu yapabilirsin.
 

peep

0
İyinet Üyesi
Onaylı Üye
Katılım
20 Mayıs 2007
Mesajlar
6,382
Reaction score
86
-angelo:
bu işlem sunucuyu rand() a göre daha azmı yorar ?
 

Angelo

0
İyinet Üyesi
Katılım
13 Aralık 2004
Mesajlar
9,603
Reaction score
111
Konum
AZ
Fazlza Kullanmadığım için MySQL'de RAND() tam bilemiyorum. Iki tip query'i analiz edip cevap zamanlarına göre karar verilebilir aslında. Varsa öyle 1 milyon verili bir tablo deneyen sonucu paylaşırsa iyi olur.
 

OsmanAtabey

0
İyinet Üyesi
Katılım
26 Mart 2005
Mesajlar
922
Reaction score
4
Şu şekilde yazdım fakat tam deneyemedim.

PHP:
$s1 = mysql_query("select `sutun1` from `tablo`");
$toplam = mysql_num_rows($s1);
$random = rand(1,$toplam);
$s2 = mysql_query("SELECT `sutun1` FROM `tablo` ORDER BY RAND() limit $random,10");

//$s2 'den alınan veriler ekrana basılıyor.

// Mysql işlemlerinden kontrol ettiğimde çıktısı da aşağıdaki gibi

Sending data	SELECT `sutun1` 
FROM `tablo` 
ORDER BY RAND( ) 
LIMIT 8792 , 10
 

Ozcan

0
İyinet Üyesi
Katılım
12 Mayıs 2007
Mesajlar
3,749
Reaction score
59
Konum
Antalya
angelo nun yazdığı ilk kod hızlı çalışır fakat 1 ile 100 arasında 5 sayı seç dedik diyelim.
1-10-15-34-56 i seçti WHERE id IN (1,10,15,34,56) kodunu yazdık. Sistemimizde 10-15 nolu kayıt silinmiş olabilir bu yüzden hata verebilir. Düzeltmek içinde bir iki tane for eklemek yerine direk sql in içinde rand() ı çalıştırmak daha mantıklı.
 

OsmanAtabey

0
İyinet Üyesi
Katılım
26 Mart 2005
Mesajlar
922
Reaction score
4
Evet kayıtlarda birkaç atlama var oralara denk gelirse sorun yaşayabilirim. Bu arada yazdığım kod sql içindeki rand() 'dan daha hızlı çalışıyor veya ben yanlış görüyorum. Benim yazdığım kodu da deneyebilecek olursa sevinirim. Bu arada benim deneme şeklim dışarıdan ayrı sayfalara gelen anlık 30 bağlantı civarında. Server adsl üzerinde bu arada.
 

Angelo

0
İyinet Üyesi
Katılım
13 Aralık 2004
Mesajlar
9,603
Reaction score
111
Konum
AZ
Maximumu bulmak icin select sutun demek yerine select max(id) kullanımı daha iyi. 5 değil güvenli olsun diye 10 tane random sayı yaratıp, php sorgunun içinde dönerken 5 tane basıldığında break; ile çıkılabilir. Atlayan sayılar kaç tane ki.
 

metadige

0
İyinet Üyesi
Katılım
23 Aralık 2005
Mesajlar
354
Reaction score
4
Arkadaşım tabii ki ilkine göre biraz daha az yorar çünkü ilkinde misal 15000 kayıttan rand yapıyorsa 2. den 8700 den sonraki kayıtlardan rand hesaplamakta. Ancak unutma ki rand le dönen sayı her zaman yüksek olmaz misal 10 da olabilir.

Bu arada id in ile seçilen veri varsa sonuç döner, yoksa hata vermez, o bakımdan sorun olmaz yani, sadece dönen veri az olabilir.

Peki şöyle bir şey yapsan, diyelim rand ile bir sayı belirleyip idi o sayıdan küçük 10 kayıt veya büyük 10 kayıt diye seçsen, işini görmez mi ?

Peşpeşe olan kayıtları çeker ancak, diğerlerine göre çok daha az yoracağı kesin.
 

OsmanAtabey

0
İyinet Üyesi
Katılım
26 Mart 2005
Mesajlar
922
Reaction score
4
Angelo arada sildiğim toplam 20 tane id no var sadece. Şu anki bayağı hızlı çalışıyor gözlemlediğim kadarıyla. Bunun üzerinde çalışayım ve dediklerini uygulayarak yapayım birde.
 

OsmanAtabey

0
İyinet Üyesi
Katılım
26 Mart 2005
Mesajlar
922
Reaction score
4
metadige sadece yüksek sayılarda çekilmiyor veriler gördüğüm kadarıyla. Anlık 30 veya 40 giriş olduğunda saçmalıyordu sql içindeki rand() normal olarak. Phpmyadmin işlemler bölümünde kontrol ettiğimde 100 tane sorguyu görebiliyordum arka arkaya.

Fakat şu ankinde en fazla 7 veya 8 tane yakalayabiliyorum. Tabiki 15 bin kayıt birşey değil daha fazla kayıt üzerinde denemek lazım bunu.

Bu arada veritabanı devamlı güncellendiği için güncel random veri almam şart. Sınırlamak istemiyorum aldığım veriyi.
 

metadige

0
İyinet Üyesi
Katılım
23 Aralık 2005
Mesajlar
354
Reaction score
4
O zaman php ile random 15 sayı seçip sqlden 10 tanesini almak daha mantıklı olabilir gibi. Örneğin:

PHP:
<?php

$al = mysql_query('select count(sutun_id) as say from tablon');
$kac = mysql_fetch_assoc($al);
$kac = $kac['say'];
for($i=0;$i<15;$i++){
$random[] = rand(1,$kac); 
}
sort($random,SORT_NUMERIC );
$random = implode(',',$random);
$query = 'select * from tablon where sutun_id in ('.$random.') limit 10';

?>
 

OsmanAtabey

0
İyinet Üyesi
Katılım
26 Mart 2005
Mesajlar
922
Reaction score
4
metadige Bu kadar karşılaştırma yapan bir fonksiyon büyük veritabanlarında sorun yaratmaz mı ?

Yaptığım sistem şu şekilde
- Sayfaya kategoriye ait içerik basılıyor örnek: 30 tane
- Bir bölüm için 10 tane random veri alınıyor.
- Başka bir bölüm için 5 tane random veri alınıyor.

Bu veritabanı ilerde en az 100 bin kayıttan oluşacak.

Bu arada count(*) ile max(id) arasında hız farkı varmıdır ?
 

metadige

0
İyinet Üyesi
Katılım
23 Aralık 2005
Mesajlar
354
Reaction score
4
Zannetmem sorun yapacağını, daha doğrusu sql'den rand() komutu ile almaktansa çok daha hızlı olur çok fazla kayıtlı tablolarda, çünkü alınacak idleri söylüyoruz sqle, 2-3K ve üzeri kayıtlı tablolarda order by rand() kullanımı zaten sakat seninde farkında olduğun gibi:)

Bunun dışında count(*) ile max(id) arasında hız farkı olur. Count(*) olarak kullanmak akıllıca değil, yukarıda kullandığım gibi count(primary_key) şeklinde kullanmalısın. Bu şekilde kullanımı gayet hızlıdır, çünkü index sütunu bilgileri tutulmaktadır.

Büyük bir taboda optimizasyon için indexleri doğru şekilde ayarlamalı ve sorgularda gereksiz bölümleri almaktan kaçınmalısın, birde online sayın çok fazla ise, basit bir şekilde cache kullanman daha iyi gibi. Yani cronjobla falan, en azından 10 dakikada dahi değişsen 100 lerce gereksiz sorgudan kurtulursun, ki giriş sayısına göre 1000 lerce de olabilir.
 

OsmanAtabey

0
İyinet Üyesi
Katılım
26 Mart 2005
Mesajlar
922
Reaction score
4
metadige

Evet az önce count(*) şeklinde kullandım ve mysql 'a erişemedim kısa bir süre. Bu günlük veritabanı güncellemesi bittiği için count(sutun) şeklini yarın denicem :)

5 dakkalık cache kullanıyorum şu anda işimi görüyor. Fakat site yeni açıldı şu anda. Bakalım ilerde ne olucak

Herkese teşekkürler
 

Invictus

0
İyinet Üyesi
Katılım
4 Şubat 2010
Mesajlar
328
Reaction score
8
Konum
istanbul
hit çok fazla olmadığı sürece order by rand() o kadar da sorun yaratmaz. metadige ve angelo nun önerisinde, id tablon sıralı değilse yani eksik varsa eksik veri gelebilir.

şu şekilde de yapabilirsin;
PHP:
$limit = 10;
$al = mysql_query('select count(id) as say from tablon');
$kac = mysql_fetch_assoc($al);
$kac = $kac['say']-$limit;
$random = rand(0,$kac)

$query = 'select * from tablon where sutun_id order by id limit '.$random.','.$limit;

bu şekilde rastgele yerden başlar ama veriyi sıralı olarak çeker.
 

OsmanAtabey

0
İyinet Üyesi
Katılım
26 Mart 2005
Mesajlar
922
Reaction score
4
Teşekkürler Invictus bu şekilde de denerim daha sonra. Şu anda fazla kayıt olmadığı için sorgulardaki problemleri göremiyorum. Şu an için deneyip gördüğüm tek şey anlık gelen 30-40 ziyaretçinin verdirdiği hatalar. Bunlarada şimdilik çözüm buldum gibi görünüyor.
 

Invictus

0
İyinet Üyesi
Katılım
4 Şubat 2010
Mesajlar
328
Reaction score
8
Konum
istanbul
random çektiğin verileri başka dosyadan çekip, mysql cache yerine file cache kullanıp nerede olması gerekiyorsa oraya dosyayı include edip de kullanabilirsin
 

OsmanAtabey

0
İyinet Üyesi
Katılım
26 Mart 2005
Mesajlar
922
Reaction score
4
Sanıyorum o tür pek de zor olmaz. Devamlı sorgu yapıp alınan veriyi dosya içine kaydettikten sonra ilgili bölümde göstermek. Şimdilik 3000 'e yakın sayfa var ve her birinin ayrı random üretmesi şart. Bunu nasıl sağlayabilirim file cache sistemi ile ?
 

Türkiye’nin ilk webmaster forum sitesi iyinet.com'da forum üyeleri tarafından yapılan tüm paylaşımlardan; Türk Ceza Kanunu’nun 20. Maddesinin, 5651 Sayılı Kanununun 4. maddesinin 2. fıkrasına göre, paylaşım yapan üyeler sorumludur.

Backlink ve Tanıtım Yazısı için iletişime geçmek için Skype Adresimiz: .cid.1580508955483fe5

seo ajansı , sosyal medya yönetimi
Üst