Jump to content
php.lv forumi

2 lietas no tabulas randomā


Artenis

Recommended Posts

Sveiki!

Radās jautājums par to kā labāk varētu dabūt 2 vērtības no tabulas laukā, pilnīgā randomā. nezimantojot rand(); ar pēc iespējas lielāku ātrdarbību, lai mazāk kaut ko noslogotu.

Pašlaik vienīgais mans variants:

<?php

$count // tabulas ierakstu skaits, kas tiek iekešots uz n laiku.


$rand=rand(0,$count);
$result=$p->db->query("select id,user ".TBL_USERS." where user!='".$id."'   limit $rand,1") or die(mysql_error());
$row=$p->db->fetch($result);
$uid[1]=$row['id'];

$rand=rand(0,($count-1));
$result=$p->db->query("select id,user ".TBL_USERS." where user!='".$id."' and id!='".$uid[1]."'   limit $rand,1") or die(mysql_error());
$row=$p->db->fetch($result);
$uid[2]=$row['id'];

?>

 

Lai cik tizli tas iespējams neizskatītos, bet šāds ir pašreizējais variants kā iegūt tās vērtības, bet īsti citu bez rand() nevaru iedomāties.

Varbūt ir kādi labi varianti? Blakus šīs vērtības gluži atrastos nedrīkstētu.

 

Paldies!

Cerams, ka domu izklāstīju pareizi.

Link to comment
Share on other sites

Priekš viena randoma ieraksta izvilkšanas izmantoju šo. Strādā ātrāk nekā mysql rand()

$r = mysql_query("SELECT count(*) FROM tabulina");  
$d = mysql_fetch_row($r);  
$rand = mt_rand(0,$d[0] - 1);    
$r = mysql_query("SELECT id, tekstins FROM tabulina LIMIT $rand, 1");
$data = mysql_fetch_assoc($r);

Link to comment
Share on other sites

Priekš viena randoma ieraksta izvilkšanas izmantoju šo. Strādā ātrāk nekā mysql rand()

$r = mysql_query("SELECT count(*) FROM tabulina");  
$d = mysql_fetch_row($r);  
$rand = mt_rand(0,$d[0] - 1);    
$r = mysql_query("SELECT id, tekstins FROM tabulina LIMIT $rand, 1");
$data = mysql_fetch_assoc($r);

 

Tad jau labāk SELECT id, tekstins FROM tabulina where id=$rand, ja id ir int un primary key. un parasti tabulās tā ir...

Protams, ja nav caurumu u.tmldz.

Edited by Milzu Lempis
Link to comment
Share on other sites

Es parasti daru tā, ka noģenerēju vairākas random vērtības (atkarībā no kopējā ierakstu skaita un maksimālā ID - nav sarežģīti aprēķināt pie cik vērtībām ir pieņemami zema neveiksmes varbūtība). Izmantojot Pentiuma kodu, tas būtu šādi:

$r = mysql_query("SELECT count(id),max(id) FROM tabulina");  
$d = mysql_fetch_row($r);
$cik_tukss = $d[1]-$d[0];
$varbutiba_ka_bus_tukss = $cik_tukss/$d[1];
$pienemama_varbutiba_ka_tukss = 0.0001;
$vismaz_tik = ceil(log($pienemama_varbutiba_ka_tukss)/log($varbutiba_ka_bus_tukss));//Protams, to var arī reizi pa reizei izrēķināt, nevis katru reizi :D
do {
$rand_array = Array();
for($x=0;$x<$vismaz_tik;$x++){
$rand_array[] = mt_rand(1,$d[1]);//protams, pavisam forši šajā vietā vēl būtu pārbaudīt, lai ģenerētās vērtības neatkārtotos, bet tas lai paliek.
} 
$r = mysql_query("SELECT id, tekstins FROM tabulina WHERE id IN (".implode(',',$rand_array).") LIMIT 1");
} while(mysql_num_rows($r)<1)
$data = mysql_fetch_assoc($r);

Link to comment
Share on other sites

LIMIT $rand,1 ir ātrākais variants (vismaz ātrāks par ORDER BY RAND() LIMIT 1), ja vien neliek klāt papildus indexētu kolonnu N (numerācijai), pēc kuras tad arī meklē: WHERE N = $rand (šādi ir ātrāk pat par to LIMIT). šāds lauks varētu būt arī id, taču tas nav ieteicams, jo DELETE radīs caurumus agrāk vai vēlāk anyway. cīņa ap šo rand performanci jau vnreiz bija (tavā pašā topikā :D) http://php.lv/f/topic/15125-liels-array-pret-lielu-db-tabulu/

toreiz izrādījās, ka parasts file read ir ātrāks par visātrāko select :D

 

kr4 ja performance ir svarīga, tad ievies kolonnu N, noindeksē to un nodrošini, lai tur būtu nepārtraukta skaitļu virkne 1..n

tad ar pirmo select uzreiz būs derīga random vērtība

 

ja id netiek dzēsti, tad, protams, var izmantot arī tos. to jau tu labāk zini. var arī selektēt pēc Alekseja piedāvātās varbūtību metodes. ja varbūtība tomēr pieviļ (tie rand id ir izdzēsti), tad šo metodi var atkārtot, kamēr ir pozitīvs rezultāts. + šai metodei ir tāds, ka nevajag taisīt vēl vienu indexētu kolonnu, bet var izmantot jau esošo id kolonnu. vsp man patīk Alekseja variants ar tām varbūtībām (krutuma ziņā). kkas velk uz kvantu datoru pusi :D

 

anyway select/where performancei vajag izmantot indexētu kolonnu. LIMIT $rand,1 ir daudz ilgāks, jo laikam notiek kkāds table scan

Edited by 2easy
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...