2012-12-18 19 views
5

Ho un database pieno di immagini, e voglio sputare e visualizzare due immagini casuali. Questo codice lo fa correttamente, ma non sono convinto che sia il modo migliore per farlo, soprattutto se il database alla fine hanno molte più righe. Ho guardato in utilizzando la funzione di MySQL rand() e limitandolo a due risultati, ma da quello che ho letto rand() è relativamente lento su grandi basi di dati. Un altro problema riguarda la doppia query del database. C'è un modo migliore per selezionare due righe casuali da img_id?selezionare due file casuali nel database MySQL

img_id è una riga auto_incremented ma non può essere considerata costante.

//get all image ids 
$query = $conn->prepare('SELECT img_id FROM images'); 
$query->execute(); 
$result = $query->fetchAll(); 

//create an array in which to put all the ids 
$list_imgs = array(); 

//put the ids into the array to search over 
for ($x=0; $x < count($result); $x++) { 
    array_push($list_imgs, $result[$x]['img_id']); 
} 

//output two random images 
for ($x=0; $x < 2; $x++) { 
    //create random index for search 
    $rand = array_rand($list_imgs); 

    //query to select one image 
    $query = $conn->prepare('SELECT title, file_loc FROM images WHERE img_id=?'); 
    //random index value in array of img_ids 
    $query->execute(array($list_imgs[$rand])); 
    $result = $query->fetchAll(); 

    echo 'title:' . $result[0]['file_loc'] . '<br /><img src="' . $result[0]['file_loc'] . '" />'; 
} 

qualche suggerimento per rendere la query più efficiente?

+0

Avete provato una query con 'ordine da rand()' contro le 3 domande che hai adesso? Tra l'altro, è possibile rendere il codice più efficiente corrente spostando la dichiarazione 'prepare' fuori dal giro, è sufficiente per preparare una volta. – jeroen

+0

ed è possibile selezionare due file casuali direttamente da '$ result', non c'è bisogno di generare un nuovo array con gli stessi valori ... – jeroen

risposta

5

si potrebbe usare

SELECT img_id, title, file_loc FROM images order by rand() limit 2 

modo che ci si finisce con

$query = $conn->prepare('SELECT img_id, title, file_loc FROM images order by rand() limit 2'); 
$query->execute(); 
$result = $query->fetchAll(); 

foreach($result as $row) { 
    echo 'title:' . $row['file_loc'] . '<br /><img src="' . $row['file_loc'] . '" />'; 
} 

Nota quell'ordine da rand() può essere particolarmente lento su tabelle di grandi dimensioni. Vedere How can i optimize MySQL's ORDER BY RAND() function? per modi di ottimizzarlo

+0

Anche se non ho mai provato io stesso, ho sentito che rand() è lento su tavoli grandi quindi sono riluttante a usarlo. Sai se c'è qualche validità a questa preoccupazione? – Hat

+0

La mia risposta ha un link in esso per modi di ottimizzare per i grandi insiemi di dati –

0

Utilizzare uno script che viene eseguito ogni x (chiamata) per contrassegnare due immagini da visualizzare.

0

Non come sicuro di questo con MySQL, in MS SQL farei:

SELECT TOP 2 img_id, newid() FROM images ORDER BY newid() 

Se funziona similmente a MySQL sarebbe

SELECT img_id, uuid() FROM images ORDER BY uuid() LIMIT 2 
0

selezionando tutte le immagini in un primo momento è eccessivo. .

si può fare someting in questo modo:

SELECT file_loc 
FROM random AS r1 JOIN 
     (SELECT (RAND() * 
        (SELECT MAX(id) 
         FROM random)) AS id) 
     AS r2 
WHERE r1.id >= r2.id 
ORDER BY r1.id ASC 
LIMIT 2 

è possibile controllare questo articolo: http://jan.kneschke.de/projects/mysql/order-by-rand/

Problemi correlati