2012-12-18 38 views
5

Tôi có một cơ sở dữ liệu đầy đủ các hình ảnh và tôi muốn nhổ ra và hiển thị hai hình ảnh ngẫu nhiên. Mã này thực hiện đúng, nhưng tôi không tin rằng đó là cách tốt nhất để làm điều đó, đặc biệt nếu cơ sở dữ liệu cuối cùng sẽ có nhiều hàng. Tôi đã xem xét việc sử dụng hàm rand() của MySQL và giới hạn nó thành hai kết quả, nhưng từ những gì tôi đã đọc rand() tương đối chậm trên các cơ sở dữ liệu lớn. Một vấn đề khác là trong truy vấn cơ sở dữ liệu kép. Có cách nào tốt hơn để chọn hai hàng ngẫu nhiên bằng img_id?chọn hai hàng ngẫu nhiên trong cơ sở dữ liệu MySQL

img_id là hàng được tự động tạo nhưng không thể được giả định là liên tục.

//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'] . '" />'; 
} 

bất kỳ đề xuất nào để làm cho truy vấn hiệu quả hơn?

+0

Bạn đã thử nghiệm một truy vấn với 'trật tự bởi rand()' chống lại 3 câu hỏi bạn có bây giờ? Bằng cách này, bạn có thể làm cho mã hiện tại của bạn hiệu quả hơn bằng cách di chuyển câu lệnh 'preparation' ra khỏi vòng lặp, bạn chỉ cần chuẩn bị một lần. – jeroen

+0

Và bạn có thể chọn hai hàng ngẫu nhiên trực tiếp từ '$ result', không cần phải tạo mảng mới với cùng giá trị ... – jeroen

Trả lời

5

bạn có thể sử dụng

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

vì vậy bạn muốn kết thúc với

$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'] . '" />'; 
} 

Lưu ý rằng thứ tự của rand() có thể đặc biệt chậm trên bảng lớn. Xem How can i optimize MySQL's ORDER BY RAND() function? để biết cách tối ưu hóa nó

+0

Mặc dù tôi chưa bao giờ thử nghiệm nó, tôi đã nghe nói rằng rand() chậm các bảng lớn nên tôi do dự khi sử dụng nó. Bạn có biết nếu có bất kỳ hiệu lực nào đối với mối quan tâm này không? – Hat

+0

Câu trả lời của tôi có một liên kết trong đó với các cách để tối ưu hóa cho các tập dữ liệu lớn –

0

Sử dụng tập lệnh được thực hiện mỗi x (cuộc gọi của bạn) để đánh dấu hai ảnh sẽ được hiển thị.

0

Không như chắc chắn về vấn đề này với MySQL, MS SQL tôi sẽ làm:

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

Nếu nó hoạt động similary trong MySQL nó sẽ là

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

chọn tất cả hình ảnh lúc đầu là quá mức cần thiết. .

bạn có thể làm someting như thế này:

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 

bạn có thể kiểm tra bài viết này: http://jan.kneschke.de/projects/mysql/order-by-rand/

Các vấn đề liên quan