Jump to content
php.lv forumi

Recommended Posts

Posted

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?

Posted

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;

Posted

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 :/)...

Posted

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 |	   |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------+

Posted (edited)

$rand=rand(count(*));

$rand2=$rand++;

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

Tā varbūt?

 

Ceru, ka šādi var

Edited by mounkuls
Posted

marrtins: kas kam nepalīdz?

 

mounkuls: vai tu pats saproti, ko dara ++ operators? Un ko nozīmē LIMIT x, y sintakse?

Posted (edited)

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
Posted

$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)

×
×
  • Create New...