Jump to content
php.lv forumi

Order by 'random'


anonīms

Recommended Posts

ORDER BY RAND() LIMIT 1 ir ļauns, ja ir daudz ierakstu (netiek izmantoti indexi)

 

Kāda pieredze ir šādiem risinājumiem? Gribētos kautko elegantāku. Viens variants varētu būt turēt vienā kolonnā (ID2) unikālus cipariņus no 0 līdz COUNT(*) un noģenerēt ar PHP $a = rand(0, COUNT(*)); SELECT * FROM tabula WHERE ID2=$a

Protams, problēma ir uzturēt to virnki 0...COUNT(*) bez caurumiem (piemēram, pēc rindas izdzēšanas).

 

Kāds elegantāks risinājums?

Link to comment
Share on other sites

v3rb0, man šķiet Mārtiņa ideja ir citādāka.

Mārtiņ, gadījumā, ja tomēr daži id ir izdzēsti, tad tava sistēma varētu nostrādāt ar kaut ko šādu:

$a = rand(0,count(*)); SELECT * FROM tabula WHERE ID>=($a-5) AND ID<($a+5) LIMIT 1;

Tas gadījumā, ja maz ticams, ka 10 pēc kārtas ir izdzēsti.

Vēl cits variants: uzģenerēt N id (nu teiksim 20 gab) interesējošajā intervālā, jo maz ticams, ka neviens no šiem N id nebūs pieejams:

for($x=0;$x<20;$x++) $a[]=rand(0,count(*));
$vaicajums='SELECT * FROM tabula WHERE ID IN ('.implode(',',$a).') LIMIT 1';

protams, lai garantēti atgrieztu rezultātu, būtu tas viss jāieliek while ciklā un jādarbina tik ilgi, līdz sakrīt.

Ā, un vēl viens variants:

$a = rand(0,count(*)); SELECT * FROM tabula WHERE ORDER BY ID2 LIMIT $a, 1;

Link to comment
Share on other sites

Jā, ciklveida pārlasīšana man arī bija prātā, taču noteikti pastāv arī kāds elegentāks risinājums :)

 

$a = rand(0,count(*)); SELECT * FROM tabula WHERE ORDER BY ID2 LIMIT $a, 1;

 

Šis varētu būt neefektīvs, ja $a ir pietiekami liels (MySQL neizmanto indexu :/)...

Link to comment
Share on other sites

Man gan rāda, ka izmanto gan:

mysql> explain select * from test order by id limit 1, 1;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------+
| id | select_type | table | type  | possible_keys | key	 | key_len | ref  | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------+
|  1 | SIMPLE	  | test  | index | NULL		  | PRIMARY | 4	   | NULL |	3 |	   |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------+

Link to comment
Share on other sites

bubu, ++ pieskaita vienu, lai gan te to nevarēja laikam lietot jo pieskaita jau pēc.

LIMIT no,līdz

Vismaz tā es to saprotu.

EDIT:

Oj, nē, nav tā.

Ir LIMIT no,cik Atvainojos!

$rand=rand(count(*));

$query="SELECT * FROM tabula LIMIT '$rand',1;";

Edited by mounkuls
Link to comment
Share on other sites

$a = rand(0,count(*)); SELECT * FROM tabula WHERE ORDER BY ID2 LIMIT $a, 1;

 

bubu, no tā indexa nav jēgas, ja $a ir pietiekami liels. Piemēram, $a=800`000 - rezultātā index teorētiski tiek izmantot, bet jēgas nekādas, jo mysql iekšienē tikuntā tiek ģenerēts 800000 rindu sets.

 

Pagaidām visefektīvākais ir Alekseja piedāvātais:

for($x=0;$x<20;$x++) $a[]=rand(0,count(*));
$vaicajums='SELECT * FROM tabula WHERE ID IN ('.implode(',',$a).') LIMIT 1';

 

Nedaudz pārveidojot:

$a = count(*);
do {
$sql = "SELECT * FROM tabula WHERE ID=".rand(0,$a)." LIMIT 1";
} while(!$r)

Link to comment
Share on other sites

×
×
  • Create New...