MySQL查询随机数据的4种方法和性能对比
发布时间:2024-01-25 17:09:46
下面从以下四种方案分析各自的优缺点。
方案一:
SELECT * FROM `table` ORDER BY RAND() LIMIT 0,1;
这种方法的问题就是非常慢。原因是因为MySQL会创建一张零时表来保存所有的结果集,然后给每个结果一个随机索引,然后再排序并返回。
有几个方法可以让它快起来。
基本思想就是先获取一个随机数,然后使用这个随机数来获取指定的行。
由于所有的行都有一个唯一的id,我们将只取最小和最大id之间的随机数,然后获取id为这个数行。为了让这个方法当id不连续时也能有效,我们在最终的查询里使用”>=”代替”=”。
为了获取整张表的最小和最大id,我们使用MAX()和MIN()两个聚合函数。这两个方法会返回指定组里的最大和最小值。在这里这个组就是我们表里的所有id字段值。
方案二:
<?php
$range_result = mysql_query( " SELECT MAX(`id`) AS max_id , MIN(`id`) AS min_id FROM `table` ");
$range_row = mysql_fetch_object( $range_result );
$random = mt_rand( $range_row->min_id , $range_row->max_id );
$result = mysql_query( " SELECT * FROM `table` WHERE `id` >= $random LIMIT 0,1 ");
就像我们刚才提到的,这个方法会用唯一的id值限制表的每一行。那么,如果不是这样情况怎么办?
下面这个方案是使用了MySQL的LIMIT子句。LIMIT接收两个参数值。第一个参数指定了返回结果第一行的偏移量,第二个参数指定了返回结果的最大行数。偏移量指定第一行是0而不是1。
为了计算第一行的偏移量,我们使用MySQL的RAND()方法从0到1之间生成一个随机数。然后我们把这个数字跟我们用COUNT()方法获取倒的表记录数相乘。由于LIMIT的参数必须是int型而不能是float,我们使用FLOOR()来处理结果。FLOOR()会计算小于表达式的最大值。最终的代码就是这样:
方案三:
<?php
$offset_result = mysql_query( " SELECT FLOOR(RAND() * COUNT(*)) AS `offset` FROM `table` ");
$offset_row = mysql_fetch_object( $offset_result );
$offset = $offset_row->offset;
$result = mysql_query( " SELECT * FROM `table` LIMIT $offset, 1 " );
在MySQL 4.1以后我们可以使用子子查询合并上面两个方法:
方案四:
SELECT * FROM `table` WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` ) ORDER BY id LIMIT 1;
这个方案跟方案二有同样的弱点,只对有唯一id值的表有效。
记住我们最初寻找选择随机行的替代方法的原因,速度!所以,这些方案的在执行时间上的比较会怎么样?我不会指出硬件和软件配置或者给出具体的数字。大概的结果是这样的:
最慢的是解决方案一(我们假定它用了100%的时间)。
方案二用了79%
方案三 – 13%
方案四 – 16%
so, 方案三胜出!


猜你喜欢
- 字典求和edge_weights = defaultdict(lambda: defaultdict(float))for idx,node
- 如果不是因为总监审查严格,一定要求这个细节解决掉,也许我也不会去深究根源性的解决办法,再此感谢MTIME负责而严格的同事。首先描述一下问题:
- 记得很早以前看到过这样的一段介绍:想象你在逛街边的一家书店,如果最终你没有购买任何图书就直接离开了,店长并不会知道你来过。但是如果你买了书,
- 最近pytorch出了visdom,也没有怎么去研究它,主要是觉得tensorboardX已经够用,而且用起来也十分的简单pip insta
- 这篇文章主要介绍了Python遍历字典方式就实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友
- asp之家注:长文章分页算是asp编程中一个比较经典单位问题,怎么分页,什么时候分页.方法挺多,有的是人为的加入分页标志,有的是程序自动加分
- 前言最近网站从HTTPS转为HTTP,更换了网址,旧网址做了301重定向,折腾有点大,于是在百度站长平台提交网址,不管是主动推送还是手动提交
- 1.通过pip安装python第三方模块paramikopip install paramiko2.创建脚本##导入paramiko、tim
- 1 configparser安装pip3 install configparser2 configparser简介用来读取配置文件的pyth
- ThinkPHP提供的视图查询应用功能十分强大,用户利用视图查询功能可以将多个数据表的字段内容按需要进行指定和筛选,组织成一个基于这些数据表
- 首先从FCKEditor官方下载最新的版本脚本之家提供的下载地址 https://www.jb51.net/codes/21294.html
- 本文实例讲述了Python Excel表格创建乘法表。分享给大家供大家参考,具体如下:题目如下:创建程序multiplicationTabl
- 多线程类似于同时执行多个不同程序,多线程运行有如下优点:使用线程可以把占据长时间的程序中的任务放到后台去处理。用户界面可以更加吸引人,比如用
- 重现的前提条件: 输出格式为“文本”的并发程序:有效责任和用户。 如何在查看输出时出现Excel选项:系统管理员》安装》浏览器选项》添加一行
- python中注释在python中的注释一般分为单行注释、多行注释以及文档注释。注释描述在实际开发过程中,有效的代码注释不仅可以提升个人的工
- 问题:一台服务器的PHP程序通过localhost地址无法连接数据库,但是如果设置为127.0.0.1则可以正常连接,连接其他数据库服务器也
- 该章节我们将要学习如何将 word 文件转为 PDF文件,其实网上有很多种生成 PDF 的教程,不过绝大多数都是以 windows 为主的,
- 我就废话不多说了,直接上代码吧!import syssys.path.append("..")from datetime
- 1. 高级用法1.1. 错误处理执行任何操作后,如果发生任何错误,GORM将其设置为*DB的Error字段if err := db.Wher
- 常规通过迭代或set方法,都无法保证去重后的顺序问题如下,我们可以通过列表的索引功能,对set结果进行序列化old_list=["