MySQLOrderByRand()效率分析
效率 分析
2023-06-13 09:14:34 时间
最近由于需要大概研究了一下MYSQL的随机抽取实现方法。举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT*FROMtablenameORDERBYRAND()LIMIT1。
但是,后来我查了一下MYSQL的官方手册,里面针对RAND()的提示大概意思就是,在ORDERBY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描。但是在MYSQL3.23版本中,仍然可以通过ORDERBYRAND()来实现随机。
但是真正测试一下才发现这样效率非常低。一个15万余条的库,查询5条数据,居然要8秒以上。查看官方手册,也说rand()放在ORDERBY子句中会被执行多次,自然效率及很低。
YoucannotuseacolumnwithRAND()valuesinanORDERBYclause,becauseORDERBYwouldevaluatethecolumnmultipletimes.
搜索Google,网上基本上都是查询max(id)*rand()来随机获取数据。
复制代码代码如下:
但是,后来我查了一下MYSQL的官方手册,里面针对RAND()的提示大概意思就是,在ORDERBY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描。但是在MYSQL3.23版本中,仍然可以通过ORDERBYRAND()来实现随机。
但是真正测试一下才发现这样效率非常低。一个15万余条的库,查询5条数据,居然要8秒以上。查看官方手册,也说rand()放在ORDERBY子句中会被执行多次,自然效率及很低。
YoucannotuseacolumnwithRAND()valuesinanORDERBYclause,becauseORDERBYwouldevaluatethecolumnmultipletimes.
搜索Google,网上基本上都是查询max(id)*rand()来随机获取数据。
SELECT*
FROM`table`ASt1JOIN(SELECTROUND(RAND()*(SELECTMAX(id)FROM`table`))ASid)ASt2
WHEREt1.id>=t2.id
ORDERBYt1.idASCLIMIT5;
但是这样会产生连续的5条记录。解决办法只能是每次查询一条,查询5次。即便如此也值得,因为15万条的表,查询只需要0.01秒不到。
下面的语句采用的是JOIN,mysql的论坛上有人使用
SELECT*
FROM`table`
WHEREid>=(SELECTFLOOR(MAX(id)*RAND())FROM`table`)
ORDERBYidLIMIT1;
我测试了一下,需要0.5秒,速度也不错,但是跟上面的语句还是有很大差距。总觉有什么地方不正常。
于是我把语句改写了一下。
SELECT*FROM`table`
WHEREid>=(SELECTfloor(RAND()*(SELECTMAX(id)FROM`table`)))
ORDERBYidLIMIT1;
这下,效率又提高了,查询时间只有0.01秒
最后,再把语句完善一下,加上MIN(id)的判断。我在最开始测试的时候,就是因为没有加上MIN(id)的判断,结果有一半的时间总是查询到表中的前面几行。
完整查询语句是:
SELECT*FROM`table`
WHEREid>=(SELECTfloor(RAND()*((SELECTMAX(id)FROM`table`)-(SELECTMIN(id)FROM`table`))+(SELECTMIN(id)FROM`table`)))
ORDERBYidLIMIT1;
SELECT*
FROM`table`ASt1JOIN(SELECTROUND(RAND()*((SELECTMAX(id)FROM`table`)-(SELECTMIN(id)FROM`table`))+(SELECTMIN(id)FROM`table`))ASid)ASt2
WHEREt1.id>=t2.id
ORDERBYt1.idLIMIT1;
最后在php中对这两个语句进行分别查询10次,
前者花费时间0.147433秒
后者花费时间0.015130秒
看来采用JOIN的语法比直接在WHERE中使用函数效率还要高很多。
相关文章
- C# 多线程 Parallel.ForEach 和 ForEach 效率问题研究及理解
- 100天精通Python丨办公效率篇 —— 07、Python自动化操作 Excel(读写、增删改查、分组统计)
- 从Linux命令行获取极致效率——强大的工具(linux命令行工具)
- 利用Oracle实例管理技术提升效率(管理Oracle实例)
- 通过Mysql整合Redis提高系统效率(mysql整合redis)
- 提升MySQL效率:建立表时创建索引(mysql建表时建立索引)
- 提升数据效率:Oracle高级数据库应用.(高级数据库oracle)
- Linux下的工作效率:提升你的码农生涯(linux效率)
- 解析Linux中文乱码问题,提升操作效率(linux中文字乱码)
- 利用Solr和Redis提高搜索和缓存效率(solr和redis)
- 「Linux代码统计工具」——高效统计代码规模,全方位分析项目开发效率!(linux 代码统计工具)
- Java与MySQL异步编程技巧——提升程序效率(javamysql异步)
- CDM查询MySQL 深入剖析查询效率(cdm 查询mysql)
- 使用笔记本装载Redis提升效率(笔记本装redis)
- 利用Redis提高注册效率的原因(用redis注册原因)
- MySQL不支持窗口函数,影响数据查询分析效率(mysql不支持窗口函数)
- Redis中的增强命令提升查询效率(增加redis命令)
- 精通Redis连接池,优化连接效率(redis连接池技巧)
- su利用Oracle RIRIMSU系统提升数据库效率(oracle ririm)
- 脚本分析、压缩、混淆工具JSA新版本发布,压缩效率提高大约10%
- Javascript字符串字节长度计算函数代码与效率分析(forVS正则)
- mysql_num_rowsVSCOUNT效率问题分析
- 基于C++执行内存memcpy效率测试的分析