最近由于需要大概研究了一下MYSQL的随机抽取实现方法。举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RAND() LIMIT 1。
但是,后来我查了一下MYSQL的官方手册,里面针对RAND()的提示大概意思就是,在ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描。但是在MYSQL 3.23版本中,仍然可以通过ORDER BY RAND()来实现随机。
但是真正测试一下才发现这样效率非常低。一个15万余条的库,查询5条数据,居然要8秒以上。查看官方手册,也说rand()放在ORDER BY 子句中会被执行多次,自然效率及很低。
You cannot use a column with RAND() values in an ORDER BY clause, because ORDER BY
would evaluate the column multiple times.
搜索Google,网上基本上都是查询max(id) * rand()来随机获取数据。
SELECT *
FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM `table`)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id ASC LIMIT 5;
但是这样会产生连续的5条记录。解决办法只能是每次查询一条,查询5次。即便如此也值得,因为15万条的表,查询只需要0.01秒不到。
下面的语句采用的是JOIN,mysql的论坛上有人使用
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
SELECT *
FROM `table`
WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` )
ORDER BY id LIMIT 1;
我测试了一下,需要0.5秒,速度也不错,但是跟上面的语句还是有很大差距。总觉有什么地方不正常。
于是我把语句改写了一下。
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
SELECT *
FROM `table`
WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` )
ORDER BY id LIMIT 1;
这下,效率又提高了,查询时间只有0.01秒
最后,再把语句完善一下,加上MIN(id)的判断。我在最开始测试的时候,就是因为没有加上MIN(id)的判断,结果有一半的时间总是查询到表中的前面几行。
完整查询语句是:
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;
SELECT *
FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`))+(SELECT MIN(id) FROM `table`)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id LIMIT 1;
最后在php中对这两个语句进行分别查询10次,
前者花费时间 0.147433 秒
后者花费时间 0.015130 秒
看来采用JOIN的语法比直接在WHERE中使用函数效率还要高很多。
http://www.cnblogs.com/phper7/archive/2010/05/26/1744063.html
分享到:
相关推荐
然而,`ORDER BY RAND()`的效率问题一直是困扰开发人员的难题。在MySQL中,直接使用`ORDER BY RAND()`对整个表进行排序,然后通过`LIMIT`获取指定数量的随机行,这种方法在大数据量时极其低效,因为它会进行全表扫描...
MySQL中的`ORDER BY RAND()`常用于实现数据集的随机排序,但其效率问题一直备受关注。在处理大量数据时,这种用法可能导致显著的性能下降。这是因为`RAND()`函数在`ORDER BY`子句中会被执行多次,对于每一行记录,都...
当你在查询的ORDER BY子句中使用RAND(),MySQL会随机地对查询结果进行排序。比如,你有一个名为`employee_tbl`的表,想要随机显示员工的信息,可以这样操作: ```sql SELECT * FROM employee_tbl ORDER BY RAND();...
举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RAND() LIMIT 1。 有两个方法可以达成以上效果. 1.新建一个表,里面存着 -5 至 5 之间的数.再利用order by ...
order by rand() 但是,后来我查了一下MYSQL的官方手册,里面针对RAND()的提示大概意思就是,在ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描。但是在MYSQL 3.23版本中,仍然可以通过ORDER ...
从执行计划、SELECT语句、IN和EXIST语句、LIMIT语句、RAND函数、Order by、Group by、Distinct和Count等方面对MySQL数据库优化进行了详细的讲解。 一、执行计划 执行计划是MySQL数据库优化的重要步骤。执行计划...
然而,当涉及到随机选择表中的记录时,单纯使用`ORDER BY RAND() LIMIT n`的方式可能会导致性能问题。因为`RAND()`函数在`ORDER BY`子句中会被执行多次,对于大数据集来说,这会极大地增加查询时间。例如,对于15万...
本文将从EXPLAIN命令、SQL语句优化、索引的使用、排序和限制、union和union all的差异、ORDER BY RAND()的优化、in和exists的区分、分页方式的优化、分段查询等角度来讨论MySQL优化策略。 一、EXPLAIN命令的使用 ...
MySQL随机查询出一条记录: 代码如下: — 下面的查询语句效率高,不要使用 SELECT * FROM table1 ORDER BY rand() LIMIT 1 来查询 SELECT * FROM table1 WHERE id=(SELECT id FROM table1 ORDER BY rand() LIMIT 1)...
SELECT * FROM table_name ORDER BY rand() LIMIT 5; rand在手册里是这么说的: RAND() RAND(N) 返回在范围0到1.0内的随机浮点值。如果一个整数参数N被指定,它被用作种子值。 mysql> select RAND(); -> 0.5925 ...