MySQL:选择多个随机行的最有效方法是什么

提问

我有一个相当大的数据集和一个需要两个联接的查询,因此查询的效率对我来说非常重要.我需要根据联接的结果从数据库中检索3个满足条件的随机行.指出Most obvious solution为低效here,因为

[these solutions] need a sequential scan of all the table (because the random value associated with each row needs to be calculated – so that the smallest one can be determined), which can be quite slow for even medium sized tables.

但是,那里的作者建议的方法(SELECT * FROM table WHERE num_value> = RAND()*(SELECT MAX(num_value)FROM table)LIMIT 1其中num_value是ID)对我不起作用,因为某些ID可能是丢失(因为某些行可能已被用户删除).

那么,在我的情况下,检索3个随机行的最有效方法是什么?

编辑:解决方案不必是纯SQL.我也使用PHP.

最佳答案

将您的RAND()调用添加到ORDER BY子句中应使您可以忽略ID.尝试这个:

SELECT * FROM table WHERE ... ORDER BY RAND() LIMIT 3;

在指出性能问题后,最好的选择是遵循以下方针(利用PHP):

$result = PDO:query('SELECT MAX(id) FROM table');
$max    = $result->fetchColumn();
$ids    = array();
$rows   = 5;

for ($i = 0; $i < $rows; $i++) {
    $ids[] = rand(1, $max);
}

$ids     = implode(', ', $ids);
$query   = PDO::prepare('SELECT * FROM table WHERE id IN (:ids)');
$results = $query->execute(array('ids' => $ids));

此时,您应该可以选择前3个结果.这种方法的唯一问题是处理已删除的行,如果您没有收到至少3个结果,则可能必须撞掉$rows var或添加一些逻辑以执行另一个查询.

评论