关于随机抽取order By Rand()的效率问题,和改进写法!

原创 2004年07月14日 00:32:00

最近由于需要大概研究了一下MYSQL的随机抽取实现方法。

举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是
SELECT * FROM tablename ORDER BY RAND() LIMIT 1

但是,后来我查了一下MYSQL的官方手册,里面针对RAND()有如下提示:
You can't use a column with RAND() values in an ORDER BY clause, because ORDER BY would evaluate the column multiple times. In MySQL Version 3.23, you can, however, do: SELECT * FROM table_name ORDER BY RAND()
大概意思就是,在ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描。但是在MYSQL 3.23版本中,仍然可以通过ORDER BY RAND()来实现随机。

然后我试了一下可行性,ORDER BY RAND()在我自己的4.0版本上可以执行,但是在公司的3.x(具体忘了)上不能执行,看来好像和官方手册上有点不同。

后来在网上找了一些资料了解到,
SELECT * FROM tablename ORDER BY RAND() LIMIT 1
会扫描整个表,然后再随机返回一个记录。对于比较小的表,通常不大于30万行记录的表,这种写法很实用。但是如果一旦记录大于了30万行,这个处理过程就会变得非常缓慢!!!

所以,结论是,我建议,能够不用ORDER BY RAND() 就不用!因为一来可以避免今后表数据量增大后引起的效率低下;二来可以避免某些版本的MYSQL不支持这种写法。
最后给出一种比较实用的替代方法的主要思想:
假设id是主键
首先:SELECT MIN(id), MAX(id) FROM tablename
然后:$id=rand($min,$max); //通过rand返回刚才取到的最大id和最小id之间的一个id号。
最后:SELECT * FROM tablename WHERE id='$id' LIMIT 1
如果是用auto increment产生的id号,也许会出现某个id列曾经删除过,造成了最大和最小id之间的不连续,在这里可以先判断一下随机生成的这个id号是否存在。


有人肯定会问:如果不是随机检索一条,而是要随机检索多条,比如10条该怎么办???

最简单的就是随便取个连续的范围,比如
SELECT * FROM tablename WHERE id > '$id' LIMIT 10
但这种方法的随机是连续的.

然后还有比如生成一个WHERE id = '{$id['1']}' OR id = '{$id['2']}' OR .....的从句,写起来会稍微多几句,$id的值随机生成数。
但这种方法如果从句多了话,比如上百条?那样SQL语句会比较大,也会影响效率。

还有,先按照第一种随机选择一个范围,比如
SELECT id FROM tablename WHERE id > '$id' LIMIT 50
然后再在在结果中随机选择10个

还有,每次随机取一个,取10次。

具体情况具体再看哪种适合。
我先能想到这么多了

ORDER BY RAND()

http://zzstudy.offcn.com/?p=2175> 由于需要大概研究了一下MYSQL的随机抽取实现方法。如:要从tablename表中随机提取一条记录,大家一般的写法...
  • qdujunjie
  • qdujunjie
  • 2014年01月23日 17:45
  • 6104

sql优化-order by rand

http://zzstudy.offcn.com/?p=2175> 由于需要大概研究了一下MySQL的随机抽取实现方法。如:要从tablename表中随机提取一条记录,大家一般的写法...
  • mico_cmm
  • mico_cmm
  • 2016年12月03日 19:04
  • 852

Hive取随机数 rand()函数

取随机数函数: rand 语法: rand(),rand(int seed) 返回值: double 说明:返回一个0到1范围内的随机数。如果指定种子seed,则会等到一个稳定的随机数序列 举...
  • qiezikuaichuan
  • qiezikuaichuan
  • 2015年03月09日 11:28
  • 11307

改进MySQL Order By Rand()的低效率

正 文:     最近由于需要研究了一下MYSQL的随机抽取实现方法。举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是: SELECT * ...
  • sean_cd
  • sean_cd
  • 2012年11月29日 13:34
  • 6080

mysql order by rand() 效率优化方法

本文将介绍如何优化mysql的order by rand()随机获取记录方法,提高查询的效率。...
  • fdipzone
  • fdipzone
  • 2016年05月30日 22:32
  • 11903

hive-随机取样

转自 http://daizj.iteye.com/blog/2273426 http://lxw1234.com/archives/2015/08/444.htm 0-Rand...
  • hjw199089
  • hjw199089
  • 2016年12月06日 20:02
  • 2308

mysql中RAND()随便查询记录效率问题和解决办法分享

在我们做开发的中效率一直是个问题,特别是对于很多大数据量操作,今天我们碰到一个要随机查询数据,一开始我们可能想到最简单的order by rand() 来操作但效率不敢恭维啊 最近由于需要大概研究了...
  • zyu67
  • zyu67
  • 2014年11月19日 09:54
  • 1539

在一个limit注入习题下的知识集合

一、mysql里面的几个函数的解释 (一) Select 查询官方解释 1. SELECT  2. [ALL | DISTINCT | DISTINCTROW ]   3. [HIGH_P...
  • zezai3010
  • zezai3010
  • 2017年12月13日 13:10
  • 41

Mysql随机取样——ORDER BY RAND()优化

The palest ink is better than best memory——好记性不如烂笔头。2013补记 一、关键词:随机取样、order by rand()二、业务场景:一款新产品上线后...
  • LoveJavaYDJ
  • LoveJavaYDJ
  • 2016年12月21日 11:49
  • 842

MYSQL随机调用order by rand(),效率太低

MYSQL随机调用order by rand(),效率太低 要从tablename表中随机提取一条记录,大家一般的写法就是: SELECT * FROM tablename ORDER...
  • peterxiaoq
  • peterxiaoq
  • 2014年01月06日 16:25
  • 759
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于随机抽取order By Rand()的效率问题,和改进写法!
举报原因:
原因补充:

(最多只允许输入30个字)