首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

PHP 實作 MySQL 隨機抽取資料:避免 ORDER BY RAND() 效能陷阱

     編輯:MySQL 資料庫相關知識

問題背景

直接使用 `ORDER BY RAND() LIMIT N` 在大表上極慢(全表掃描 + 檔案排序)。本文示範 兩階段隨機抽取法:先抽取主鍵 ID 陣列,再以隨機 ID 精確查詢。

完整 PHP 程式碼

<?php
header("Content-Type: text/html; charset=utf-8");

$host = 'localhost'; $user = 'root'; $pass = '123456';
$db   = 'mytestdb';  $tbl  = 'mytesttable';

$conn = mysql_connect($host, $user, $pass) or die('MySQL connect error!');
mysql_select_db($db, $conn);

// 1. 取得所有符合條件的 ID
$res = mysql_query("SELECT id FROM `$tbl`", $conn) or die('select id error');
$ids = array();
while ($row = mysql_fetch_assoc($res)) {
    if (is_numeric($row['id'])) $ids[] = $row['id'];
}
mysql_free_result($res);

// 2. 隨機挑一個 ID 精確查詢
if (count($ids) > 0) {
    $rand_id = $ids[array_rand($ids, 1)];
    $res = mysql_query("SELECT * FROM `$tbl` WHERE id = $rand_id", $conn) or die('select detail error');
    $row = mysql_fetch_assoc($res);
    $output = "{$row['foodname']}{$row['price']}{$row['tel']}";
    mysql_free_result($res);
} else {
    $output = 'Without any data';
}
mysql_close($conn);
echo $output;
?>

進階優化:大表適用的 SQL 寫法

-- 利用主鍵範圍隨機,避免全表掃描
SELECT * FROM `table` 
WHERE id >= (SELECT FLOOR(RAND() * ((SELECT MAX(id) FROM `table`) - (SELECT MIN(id) FROM `table`))) + (SELECT MIN(id) FROM `table`))
ORDER BY id LIMIT 1;

配合 `JOIN` 寫法效能更佳(見文章 89196)。

棄用 `mysql_*` 函數提醒

範例為教學用途,實務請改用 PDO 或 mysqli(支援預處理、防注入、PHP 7+ 相容)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved