当前位置:首页 > 编程教程 > mysql技术文章 > MySQL查询随机数据的4种方法和性能对比

MySQL查询随机数据的放在总结和性能分析

  • 发布时间:
  • 作者:码农之家
  • 点击:76

这篇文章主要知识点是关于MySQL、MySQL随机数、mysql随机查询若干条数据的方法 的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

PHP和MySQL Web开发
PHP和MySQL Web开发中文高清第5版
  • 类型:PHP网站开发大小:27 MB格式:PDF作者:卢克·韦林
立即下载

MySQL查询随机数据的4种方法和性能对比

下面从以下四种方案分析各自的优缺点。
方案一:
 
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, 方案三胜出!

mysql随机查询若干条数据的方法

在mysql中查询5条不重复的数据,使用以下:


SELECT * FROM `table` ORDER BY RAND() LIMIT 5

就可以了。但是真正测试一下才发现这样效率非常低。一个15万余条的库,查询5条数据,居然要8秒以上
搜索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;

最后对这两个语句进行分别查询10次,
前者花费时间 0.147433 秒
后者花费时间 0.015130 秒
看来采用JOIN的语法比直接在WHERE中使用函数效率还要高很多。

以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。

MySQL查询随机数 相关电子书
学习笔记
网友NO.614312

MYSQL随机抽取查询 MySQL Order By Rand()效率问题

要从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; 但是这……

网友NO.204868

MySQL随机查询记录的效率测试分析

以下就是文章的主要内容。 1.SELECT * FROM `table` ORDER BY RAND() LIMIT 5 就可以了。 但是真正测试一下才发现这样效率非常低。一个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()来随机获取数据。 1.SELECT * 2.FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM `table`)) AS id) AS t2 3.WHERE t1.id = t2.id 4.ORDER BY t1.id ASC LIMIT 5; 但是这样会产生连续的5条记录。解决办法只能是每次查询一条,查询5次。即便如此也值得,因为15万条的表,查询只需要0.01秒不到。 上面的语句采用的是JOIN,MySQL的论坛上有人MySQL使用 1.SELECT * 2.FROM `table` 3.WHERE id = (SELECT FLOOR( MAX(id) * R……

网友NO.143478

mysql实现随机查询经验谈

一、随机查询一条数据 方法一:SELECT * FROM `table` ORDER BY RAND() limit 1 评价:不建议使用,效率非常低,官方文档中进行说明:Order By和RAND()连用,会多次扫描表,导致速度变慢。 方法二:SELECT * FROM `table` WHERE id = (SELECT floor(RAND() * (SELECT MAX(id) FROM `table`))) ORDER BY id LIMIT 1; 解释:SELECT MAX(id) FROM `table` 这句话查询出最大的id值 SELECT floor(RAND() * (SELECT MAX(id) FROM `table`)) 这句获取一个小于MAX(id)的随机数 WHERE id = (SELECT floor(RAND() * (SELECT MAX(id) FROM `table`))) 这句话筛选出所有的大于生成随机数的id的行 然后最后就把大于这个随机id的行查询出来,然后按照id排序,选择第一个,就相当与获取了所有行中随机的一行。 评价:有问题,如果id不是从0开始的话,比如从10000开始自增,那么 SELECT floor(RAND() * (SELECT MAX(id) FROM `table`)) 得到的将是会哟很大概率得到小于10000的值,经……

网友NO.986192

MySQL 随机查询数据与随机更新数据实现代码

MySQL随机查询数据 以前在群里讨论过这个问题,比较的有意思.MySQLl的语法真好玩.他们原来都想用PHP的实现随机,但取出多条好像要进行两次以上查询.翻了手册,找到了下面这个语句,可以完成任务了。 SELECT * FROM table_name ORDER BY rand() LIMIT 5; MySQL的rand()函数在手册里是这么说的: RAND() RAND(N) 返回在范围0到1.0内的随机浮点值。如果一个整数参数N被指定,它被用作种子值。 关于MySQL的rand()函数的效率问题,大家可以参考《MySQLL Order By Rand()效率》:http://www.phpq.net/MySQLl/MySQLl-order-by-rand.html 实际效果 MySQLl select RAND(); - 0.5925 MySQLl select RAND(20); - 0.1811 MySQLl select RAND(20); - 0.1811 MySQLl select RAND(); - 0.2079 MySQLl select RAND(); - 0.7888 MySQL随机更新数据 如何写一个语句能一下更新几百条MySQLL数据! 需要测试MySQL数据库,里面有一个上万条数据的数据库,如何写一个PHP文件一下每次更……

<
1
>

Copyright 2018-2020 www.xz577.com 码农之家

投诉 / 推广 / 赞助:QQ:520161757