[mysql] MySQL Order By Rand()效率【转载】
最近由于需要大概研究了一下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的论坛上有人使用
SELECT *
FROM `table`
WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` )
ORDER BY id LIMIT 1;
我测试了一下,需要0.5秒,速度也不错,但是跟上面的语句还是有很大差距。总觉有什么地方不正常。
于是我把语句改写了一下。
SELECT *
FROM `table`
WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` )
ORDER BY id LIMIT 1;
这下,效率又提高了,查询时间只有0.01秒
最后,再把语句完善一下,加上MIN(id)的判断。我在最开始测试的时候,就是因为没有加上MIN(id)的判断,结果有一半的时间总是查询到表中的前面几行。
完整查询语句是:
1 SELECT * FROM `table`
2 WHERE id >= (SELECT floor( RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`)) + (SELECT MIN(id) FROM `table`)))
3 ORDER BY id LIMIT 1;
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中使用函数效率还要高很多。
[mysql] MySQL Order By Rand()效率【转载】的更多相关文章
- MYSQL随机抽取查询 MySQL Order By Rand()效率问题
MYSQL随机抽取查询:MySQL Order By Rand()效率问题一直是开发人员的常见问题,俺们不是DBA,没有那么牛B,所只能慢慢研究咯,最近由于项目问题,需要大概研究了一下MYSQL的随机 ...
- MySQL的Order By Rand()的效率问题
MySQL很多时候需要获取随机数据,举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是: 但是,后来我查了一下MYSQL的官方手册,里面针对RAND()的提示大概意思就是,在OR ...
- MySQL Order By Rand()效率
最近由于需要大概研究了一下MYSQL的随机抽取实现方法.举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RA ...
- MySQL Order By Rand()效率分析
最近研究了一下MYSQL的随机抽取实现方法.举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RAND() L ...
- MySQL 中随机抽样:order by rand limit 的替代方案
最近由于需要大概研究了一下MYSQL的随机抽取实现方法.举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RA ...
- 【MySQL性能优化】改进MySQL Order By Rand()的低效率
<a href="http://click.aliyun.com/m/9153/">点击查看原文</a> 正 文: 最近由于需要研究了一下MYSQL的随 ...
- 改进MySQL Order By Rand()的低效率
Author:flymorn Source:飘易Categories:PHP编程 PostTime:2011-1-14 15:35:07 正 文: 最近由于需要研究了一下MYSQL的随机抽取实现方法. ...
- mysql order by rand() 优化方法
mysql order by rand() 优化方法 适用于领取奖品等项目<pre>mysql> select * from user order by rand() limit 1 ...
- MySQL中的RAND()函数使用详解(order by rand() 随机查询取前几条记录)
MySQL RAND()函数调用可以在0和1之间产生一个随机数: mysql> SELECT RAND( ), RAND( ), RAND( ); +------------------+--- ...
随机推荐
- PO_标准采购流程请购采购接受入库(流程)
2014-06-03 Created By BaoXinjian
- Error parsing XML: not well-formed (invalid token) 报错
鼠标右键选择Source然后再选Format 就可以解决此问题
- [转]HSpice仿真
一.HSPICE基础知识Avant! Start-Hspice(现在属于Synopsys公司)是IC设计中最常使用的电路仿真工具,是目前业界使用最为广泛的IC设计工具,甚至可以说是事实上的标准.目前, ...
- 连接mysql-front数据库出现‘执行错误1251’的解决办法(有效)
原因是MySQL8.0版本的加密方式和MySQL5.0的不一样,连接会报错. 解决方法:更改加密方式 控制台中先连接mysql: 再输入: ALTER USER 'root'@'localhost' ...
- enumerate的简单使用
l = [11,22,33,55,"ss","zz"] for i,v in enumerate(l): print(i,v) #打印结果: # 0 11 # ...
- 怎么使用 ab.exe 测试多个url。 how to use ab.exe test many url
from a commandline in windows: for /F %q in (list.txt) DO ab -n 1000 https://test.com/search?%q I ...
- Spring Bean的生命周期详解(转)
Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...
- Android开发之控制摄像头拍照
如今的手机一般都会提供相机功能,有些相机的镜头甚至支持1300万以上像素,有些甚至支持独立对焦.光学变焦这些仅仅有单反才有的功能,甚至有些手机直接宣传能够拍到星星.能够说手机已经变成了专业数码相机.为 ...
- Codeforces Round #262 (Div. 2) C
题目: C. Present time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...
- 正则表达式入门(c#)
本文是对该教程的学习练习 http://www.jb51.net/tools/zhengze.html 注:正则符号转义和普通的转义一样,加反斜杠,比如[ 变成 \[ 正则表达式符号和转义符号最好用+ ...