MYSQL 随机 抽取实现方法及效率分析

  • 更新时间:2023-01-11 17:08:12
  • 编辑:詹元甲
给寻找编程代码教程的朋友们精选了MYSQL相关的编程文章,网友那经纬根据主题投稿了本篇教程内容,涉及到MYSQL、随机相关内容,已被456网友关注,如果对知识点想更进一步了解可以在下方电子资料中获取。

参考资料

正文内容

 

请教怎么从数据库随机读出15条记录?
order by rand() limit 0,15
怎么从数据库随机读出所有记录?
order by rand()

但是,后来我查了一下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;

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中使用函数效率还要高很多。

MYSQL相关教程

  • 解决Mybatis逆向工程中使用Mysql8.0版本驱动遇到的问题

    今天在使用 8.0.12 版的 mysql 驱动时遇到了各种各样的坑。这篇文章主要介绍了详解Mybatis逆向工程中使用Mysql8.0版本驱动遇到的问题,感兴趣的小伙伴们可以参考一下

    发布时间:2019-06-18

  • 分享mysql简单实现查询结果添加序列号的代码

    这篇文章主要介绍了mysql简单实现查询结果添加序列号的方法,结合实例形式演示了2种查询结果添加序列号的技巧,具有一定参考借鉴价值,需要的朋友可以参考下

    发布时间:2020-02-16

  • MySQL存储引擎InnoDB的配置及使用方法

    今天小编就为大家分享一篇关于MySQL存储引擎InnoDB的配置与使用的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    发布时间:2019-08-29

  • Windows Server 2008 R2和2012中PHP连接MySQL过慢的原因

    这篇文章主要介绍了Windows Server 2008 R2和2012中PHP连接MySQL过慢的解决方法,同时对Windows 7和8的本地开发环境也有效,需要的朋友可以参考下

    发布时间:2019-12-04

  • mysql存储过程实现循环插入100条记录

    本节主要介绍了使用存储过程实现循环插入100条记录的具体实现,需要的朋友可以参考下

    发布时间:2020-05-16

  • 64位Win10系统安装Mysql5.7.11的步骤

    小编在安装64位Win10系统的mac book笔记本上用mysql-installer-community-5.7.11.0安装Mysql5.7.11,在配置mysql server时老是卡住,报错。下面小编把安装方法分享给大家,供大家参考

    发布时间:2019-06-18

  • 《PHP和MySQL Web开发》知识点总结(一)

    前言 简要记录了PHP的标识符,变量,常量,作用域,操作符及变量的几个常用函数。 标识符 PHP中变量的标识符由$开头,后接字母,数字,下划线。 变量的标识符区分大小写。如 $var 与 $VAR 是不同的。 函数的标识符不区分大小写! 对 FOO() 与 foo() 进行的是等价的调用。 一个变量的名称可以和函数的名称相同,但是不建议这么做。 变量 PHP变量有以下几种数据类型: Integer (整数

    发布时间:2018-08-17

  • Oracle和MySQL的高可用方案对比及用法详解

    这篇文章主要介绍了Oracle和MySQL的高可用方案对比分析,非常不错,具有参考借鉴价值,需要的朋友可以参考下

    发布时间:2020-07-26

  • PHP结合Redis+MySQL实现冷热数据交换应用案例详解

    PHP结合Redis+MySQL实现冷热数据交换应用案例详解

    为网友们分享了关于PHP的教程,这篇文章主要介绍了PHP结合Redis+MySQL实现冷热数据交换应用案例,结合具体实例形式详细分析了Redis+MySQL冷热数据交换原理、实现方法及相关操作技巧,需要的朋友可以参考下

    发布时间:2022-06-26

用户留言