0

我读过一篇关于如何从包含大量数据的 SQL 表中随机选择一行(在某些条件下)的文章。他们得到 id 的最大值和最小值,并在它们之间生成一个随机数,并得到第一行的 id 比那个大。但是,我的 id 分布不均匀,所以我没有得到真正随机的行。例如,如果我的 id 是 1、100、101,我将几乎没有机会获得后面的两行。

但我想到了另一种解决方案。我没有获取最大 id,而是计算查询中的所有行,获取一个随机数 i 并选择第 i 个。代码看起来像这样

$count_res = $mysqli->query("SELECT COUNT(*) FROM quest WHERE category IN ({$mem['my_cate']})");
$count = $count_res->fetch_array();
$rand_id = rand(0, $count[0] - 1);

$result = $mysqli->query("SELECT * FROM quest WHERE category IN ({$mem['my_cate']}) LIMIT 1 OFFSET $rand_id");

但是,我怀疑它的有效性。任何人都可以给我一些想法,或者为我的案例提出解决方案。谢谢。

4

2 回答 2

1

好吧,我已经做了一些基准测试。我创建了一个表,其中只有一列具有自动增量 ID。然后我添加了 1,700,000 条记录。由于只有一列,我想它会比实际更快,但这是我的基准测试:

方法1:选择行数,然后使用PHP选择一个随机数,然后根据偏移量进行选择。(我将偏移量设置在表格的末尾,因为它会比表格的开头慢)。

选择计数:12ms

选择偏移:513ms

总计:525ms

方法 2:在整个表上使用 RAND() 选择 1。

总计:2,190 毫秒

获胜者 = 方法 1

可能的方法3:这只是我想出来的,它不一定适用于所有情况。所以想法是你得到表中最后一个自动增量 id,生成一个介于 1 和最后一个自动增量号之间的随机数,然后选择大于或等于该 id 号的第一行。您必须做大于或等于,因为可能会丢失 id 号码。

选择最后一个id:10.1ms

选择随机行:6.3ms

总计:16.4ms

于 2013-05-26T05:33:42.873 回答
-2

使用类似的东西可能会更快:

$result = $mysqli->query("SELECT * FROM quest WHERE category IN ({$mem['my_cate']}) ORDER BY Rand() LIMIT 1");

因为它只使用一个查询,你可以跳过那个最高位。您可以通过在循环中尝试两种方式来对其进行基准测试,几千次或您决定的任何次数,并比较循环前后的 microtime()。

于 2013-05-26T03:07:37.420 回答