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(RAND() * (SELECT MAX(id) 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;
最后在php中对这两个语句进行分别查询10次,前者花费时间 0.147433 秒,后者花费时间 0.015130 秒。看来采用JOIN的语法比直接在WHERE中使用函数效率还要高很多。
不过这种方式调用的记录会存在id连号的问题。
MySQL的Order By Rand()的效率问题的更多相关文章
- MYSQL随机抽取查询 MySQL Order By Rand()效率问题
MYSQL随机抽取查询:MySQL Order By Rand()效率问题一直是开发人员的常见问题,俺们不是DBA,没有那么牛B,所只能慢慢研究咯,最近由于项目问题,需要大概研究了一下MYSQL的随机 ...
- MySQL Order By Rand()效率
最近由于需要大概研究了一下MYSQL的随机抽取实现方法.举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RA ...
- 【MySQL性能优化】改进MySQL Order By Rand()的低效率
<a href="http://click.aliyun.com/m/9153/">点击查看原文</a> 正 文: 最近由于需要研究了一下MYSQL的随 ...
- [mysql] 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()的低效率
Author:flymorn Source:飘易Categories:PHP编程 PostTime:2011-1-14 15:35:07 正 文: 最近由于需要研究了一下MYSQL的随机抽取实现方法. ...
- MySQL 中随机抽样:order by rand limit 的替代方案
最近由于需要大概研究了一下MYSQL的随机抽取实现方法.举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RA ...
- 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( ); +------------------+--- ...
随机推荐
- 安装Mysql提示1045错误解决方法
MySQL安装提示一下错误 The security settings could not be applied to the database because the connection has ...
- 添加一个功能Action
1,只用一个handler类,所有都事件的处理器都在一个handler类 handler要创建以Action为名称的方法 event要单独分开,继承KDEvent package com.kingde ...
- Spider爬虫清洗数据(re方法)
import re s0 = 'BOY and GIRL' s1 = re.sub(r'BOY|GIRL', 'HUMAN', s0) print s1 # HUMAN and HUMAN 替换方法.
- C++ 动态数组实例
一维动态数组的实例: #include <iostream> using namespace std; int main() { int *arr; int n; cout<< ...
- oneM2M启动Release 3标准化,华为引领物联网技术布局
http://developer.huawei.com/cn/ict/news/cn/2016/06/onem2m [韩国,首尔,2016年6月] 国际权威的物联网组织oneM2M召开第23次技术全会 ...
- 在浏览器输入 URL 后会发生什么?超级详细介绍
一个古老的面试问题:当你在浏览器中输入whosmall.com并且按下回车之后发生了什么? 不过我们不再局限于平常的回答,而是想办法回答地尽可能具体,不遗漏任何细节. 这将是一个协作的过程,所以深入挖 ...
- lua 闭包
--匿名函数使用upvalue i保存他的计数, 闭包是一个函数加上它可以正确访问的upvalues function newCounter() return function() i = i + r ...
- PyQ1_介绍
PyQt是一个创建GUI应用程序的工具包.它是Python编程语言和Qt库的成功融合.Qt库是目前最强大的库之一.PyQt是由Phil Thompson 开发. PyQt实现了一个Python模块 ...
- 给ubuntu的docky添加可以直接打开的图标
在/usr/share/applications和/usr/share/app-install/desktop寻找需要的图标,没有就自己做一个 eclipse的图标 [Desktop Entry] V ...
- Java观察者设计模式
在java.util包中提供了Observable类和Observer接口,使用它们即可完成观察者模式. 多个观察者都在关注着价格的变化,只要价格一有变化,则所有的观察者会立即有所行动. //==== ...