从表中选择一个随机记录,为什么第一个慢于第二个?

时间:2015-08-07 03:51:32

标签: mysql sql

我想从一张大桌子中选择一张随机记录。搜索完毕后,最终找到了两个解决方案;

一个:

select id  from `table` where id = (floor(1 + rand() * 2880000));

b:

select id  from `table` where id >= (floor(1 + rand() * 2880000)) limit 1;

但是,第一个(a)解决方案比第二个(b)慢得多,大约慢慢40倍。

执行多次后,我发现了一个更奇怪的问题。第一种解决方案可能会返回两条记录。

select id  from `table` where id = (floor(1 + rand() *  2880000));
+---------+
| id      |
+---------+
| 2484024 |
| 1425029 |
+---------+
2 rows in set (1.06 sec)

我的问题是:

  • 为什么第一种解决方案比第二种解决方案慢?
  • 为什么第一个解决方案会返回两个记录?

我的MySQL版本:

mysql> show variables like "%version%";
+-------------------------+-------------------------+
| Variable_name           | Value                   |
+-------------------------+-------------------------+
| innodb_version          | 5.5.43                  |
| protocol_version        | 10                      |
| slave_type_conversions  |                         |
| version                 | 5.5.43-0ubuntu0.12.04.1 |
| version_comment         | (Ubuntu)                |
| version_compile_machine | x86_64                  |
| version_compile_os      | debian-linux-gnu        |
+-------------------------+-------------------------+
7 rows in set (0.04 sec)

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

你的两个问题的答案:

  1. 第一个解决方案比第二个解决方案慢,因为在第一个解决方案中,为每个记录计算新的随机值,而在第二个解决方案中,仅计算找到一个匹配所需的记录。另请注意,第二种解决方案的条件要严格得多。
  2. 您可以在第一个解决方案中拥有多个返回值,因为为每个记录计算了一个新的随机值,并且您没有限制语句。按照相同的逻辑,你也可以有0个结果。
  3. 请查看this answer以获得更好的解决方案。

答案 1 :(得分:0)



SELECT 
    a.id
FROM
    tableA a
        INNER JOIN
    (SELECT 
        (ROUND((RAND() * (MAX(id) - MIN(id))) + MIN(id)) - 1) r
    FROM
        tableA) x
WHERE
    a.id > x.r
LIMIT 1;