随机取5条记录怎么取?

rczjp 2011-04-06 01:17:15
随机在A表里面取5条记录怎么取?不能重复
不能使用 ORDER BY RAND(),因为效率太差了
...全文
301 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
helloyou0 2011-04-08
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 foolbirdflyfirst 的回复:]

试下下面这个,可以消除filesort
PHP code
SELECT * FROM (
SELECT @cnt := COUNT(*) + 1,
@lim := 5
FROM 表名
) vars STRAIGHT_JOIN(
SELECT r.*, ……
[/Quote]


这个写法很巧妙,
但是,在大数据量的情况下,似乎不如5个id〉的方法?
rczjp 2011-04-07
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 foolbirdflyfirst 的回复:]
试下下面这个,可以消除filesort

PHP code
SELECT * FROM (
SELECT @cnt := COUNT(*) + 1,
@lim := 5
FROM 表名
) vars STRAIGHT_JOIN(
SELECT r.*, ……
[/Quote]恩,不错,第一次看见这种写法呵呵
rczjp 2011-04-07
  • 打赏
  • 举报
回复
感谢大家的回帖,综合大家的意见

数量少可以直接随机,也可以保存数组再打乱
数量大先打乱数据保存到临时表(缓存文件)
foolbirdflyfirst 2011-04-07
  • 打赏
  • 举报
回复
试下下面这个,可以消除filesort
SELECT  * FROM    (         
SELECT @cnt := COUNT(*) + 1,
@lim := 5
FROM 表名
) vars STRAIGHT_JOIN(
SELECT r.*,
@lim := @lim - 1
FROM 表名 r
WHERE (@cnt := @cnt - 1)
AND RAND() < @lim / @cnt
) i
gwn1902 2011-04-07
  • 打赏
  • 举报
回复
取最新的100条记录 然后从数组中随机读取五条呗
helloyou0 2011-04-07
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 rczjp 的回复:]

恩,后来我也是这么做,不过数据量大了效率也很低
PHP code
function GetRandRecord(){
$arr = array();
$row_num = $db->result_first("SELECT count(*) FROM a WHERE");
while(true){
$query1 = $db->query("SELECT floor(……
[/Quote]

你这个查询可以不放在循环里面每次都做,
$query1 = $db->query("SELECT floor(RAND() * (SELECT MAX(id) FROM a)+1)");


另,16楼的方法就很好,和你的大体一样,但是用了<或>可以每次都得到一个结果


另另,看你的id分布,
如果id分布密集,用rand(1,max(id))生成〉5个(比如搞个10个)
然后用 in (x1,x2。。。)这样一次取出来, mysql对有索引的列上做in还是比较快的


另另另,如果什么方法都不快,升级服务器。。。。。。降低需求,比如只取随机一个。。。。。比如用假随机(楼上各种)

















rczjp 2011-04-07
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 zhuyuejianke 的回复:]
方法2(数据量非常大的时候)

1、取所有记录ID,保存为数组$ids
2、数组$ids序列化(json化,serialize($ids)),再保存成缓存文件ids.php
3、用的时候file_get_contents 为字符串$ids,字符串转数组unserialize($ids)。
4、随机数组。
[/Quote]缓存文件,可以考虑,谢谢
rczjp 2011-04-07
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 zhuyuejianke 的回复:]
这有啥难度?

难道不是这样吗?

1、取总记录$rs
2、$rs转数组$rs,数组随机函数array_rand($rs,5)。
[/Quote]array_rand 这个打乱的是索引? 可以打乱值吗?
rczjp 2011-04-07
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 zhang6464 的回复:]
不要求纯粹随机的话可以仅仅采用随机偏移量的方式,例如你想取到最新入库的100条数据的随机5条,在php端$rand=rand(1,95),取到一个偏移量,然后取limit $rand,5,以此类推,然后如果想扩大范围的话,可以加一个量级,即$lev=rand(0,100),然后取limit ($rand+$lev*100),5,或者直接令rand的范围足够大也可以
[/Quote]恩谢谢,不过判断很多
张小莱 2011-04-07
  • 打赏
  • 举报
回复
如果没有“一定要不连串的数据”规定的话好做。
比如一共有1000条数据。
$num = rand(0,996);
$sql = "SELECT * FROM `my_table` limit " . $num. ",5";
搞定!呵呵~

小在在 2011-04-07
  • 打赏
  • 举报
回复
再来一个思路:
1.生成并检测: 写一个函数生成随机ID,检测数据库中存在否并且过滤掉重复值.
将这些值放在一个数组中$a;
2.取数据: 这个过程就最直接了,直接SQL写语句
SELECT * FROM A WHERE ID IN($a[0],$a[1],$a[2],$a[3],$a[4])....
这样直接取出5条随机记录.

要说这个思路有些麻烦的地方,就是在第1点中,要检测存在.
不过只是判断一下而非取数据应该会提升不少效率的
阳光树影 2011-04-07
  • 打赏
  • 举报
回复
挺开阔思路的,好帖
zhuyuejianke 2011-04-06
  • 打赏
  • 举报
回复
补充:方法一有误,应该是随机1-10 7次。7次结果相乘。或者7个随机0-9数字组成一个随机数n,然后sql:limit 1,n。

zhuyuejianke 2011-04-06
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 zhang6464 的回复:]
引用 14 楼 zhuyuejianke 的回复:

方法2(数据量非常大的时候)

1、取所有记录ID,保存为数组$ids
2、数组$ids序列化(json化,serialize($ids)),再保存成缓存文件ids.php
3、用的时候file_get_contents 为字符串$ids,字符串转数组unserialize($ids)。
4、随机数组。
有一千万条数据的话,你拿……
[/Quote]

1000万条数据,就不必执着于是否真的从这1000万条随机了,又不是彩票。

方法1:可以随机从0-100里取出一个数字3次,三次相乘得到一个数字n,第多少条,然后limit n,1。

方法2:或者看看你的自增量id是多少位,是多少位,就分别随机0-9多少次。得到准确的ID,成功则返回,失败则再随机直到成功。
lazyboy_wu 2011-04-06
  • 打赏
  • 举报
回复
给你看下我以前反的一个帖子,很早了

http://topic.csdn.net/u/20070827/15/7b8b235b-66d8-4c93-aee9-fe8b58fa9d45.html
zhang6464 2011-04-06
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 zhuyuejianke 的回复:]

方法2(数据量非常大的时候)

1、取所有记录ID,保存为数组$ids
2、数组$ids序列化(json化,serialize($ids)),再保存成缓存文件ids.php
3、用的时候file_get_contents 为字符串$ids,字符串转数组unserialize($ids)。
4、随机数组。
[/Quote]有一千万条数据的话,你拿数组去存这么多id?
zhuyuejianke 2011-04-06
  • 打赏
  • 举报
回复
方法2(数据量非常大的时候)

1、取所有记录ID,保存为数组$ids
2、数组$ids序列化(json化,serialize($ids)),再保存成缓存文件ids.php
3、用的时候file_get_contents 为字符串$ids,字符串转数组unserialize($ids)。
4、随机数组。
zhuyuejianke 2011-04-06
  • 打赏
  • 举报
回复
这有啥难度?

难道不是这样吗?

1、取总记录$rs
2、$rs转数组$rs,数组随机函数array_rand($rs,5)。
zhang6464 2011-04-06
  • 打赏
  • 举报
回复
不要求纯粹随机的话可以仅仅采用随机偏移量的方式,例如你想取到最新入库的100条数据的随机5条,在php端$rand=rand(1,95),取到一个偏移量,然后取limit $rand,5,以此类推,然后如果想扩大范围的话,可以加一个量级,即$lev=rand(0,100),然后取limit ($rand+$lev*100),5,或者直接令rand的范围足够大也可以
LiveAsaMonster 2011-04-06
  • 打赏
  • 举报
回复
不会
加载更多回复(10)

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧