我有一个相当大的数据集和一个需要两个联接的查询,因此查询的效率对我来说非常重要。我需要根据联接的结果从数据库中检索3个满足条件的随机行。这里指出最明显的解决方案效率低下,因为
[这些解决方案]需要对所有表进行顺序扫描(因为需要计算与每一行关联的随机值-以便可以确定最小的行),即使对于中等大小的表也可能相当慢。
但是,那里的作者建议的方法(SELECT * FROM table WHERE num_value >= RAND() * (SELECT MAX(num_value) FROM table) LIMIT 1其中num_value是ID)对我不起作用,因为某些ID可能会丢失(因为某些行可能已被用户删除)。
SELECT * FROM table WHERE num_value >= RAND() * (SELECT MAX(num_value) FROM table) LIMIT 1
那么,在我的情况下,检索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个结果,则可能必须撞掉$ rowsvar或添加一些逻辑以执行另一个查询。