MYSQL的随机抽取实现方法。举个例子,要从tablename表中随机提取一条记录,你们通常的写法就是:SELECT * FROM tablename ORDER BY RAND() LIMIT 1。php
可是,后来我查了一下MYSQL的官方手册,里面针对RAND()的提示大概意思就是,在ORDER BY从句里面不能使用RAND()函数,由于这样会致使数据列被屡次扫描。可是在MYSQL 3.23版本中,仍然能够经过ORDER BY RAND()来实现随机。mysql
可是真正测试一下才发现这样效率很是低。一个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秒不到。sql
下面的语句采用的是JOIN,mysql的论坛上有人使用 SELECT * FROM table
WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM table
) ORDER BY id LIMIT 1;数据库
我测试了一下,须要0.5秒,速度也不错,可是跟上面的语句仍是有很大差距。总觉有什么地方不正常。mybatis
因而我把语句改写了一下。 SELECT * FROM table
WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM table
))) ORDER BY id LIMIT 1;dom
这下,效率又提升了,查询时间只有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;ui
最后在php中对这两个语句进行分别查询10次, 前者花费时间 0.147433 秒 后者花费时间 0.015130 秒 看来采用JOIN的语法比直接在WHERE中使用函数效率还要高不少
分享到:
正则表达式之道 | Mysql的经常使用命令 2011-03-30 15:18浏览 44070评论(8)分类:数据库相关推荐 参考知识库
PHP知识库 370 关注 | 289 收录
MySQL知识库 9323 关注 | 1396 收录 评论 8 楼 hao3721 2015-08-04
SELECT t1.gv_title
AS title
,t1.gv_ico_key
AS icon
,t1.gv_id
,t1.gv_package_name
FROM mzw_game_version
AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(gv_id) FROM mzw_game_version
)-(SELECT MIN(gv_id) FROM mzw_game_version
))+(SELECT MIN(gv_id) FROM mzw_game_version
)) AS gv_id) AS t2 WHERE t1.gv_id >= t2.gv_id AND t1.gv_type_id
=8 ORDER BY t1.gv_id LIMIT 4;
加了条件后,有时能够取4条,有时取2条,有时1条,有时一条也没有,这样不对的吧? 7 楼 yibuyimeng 2015-05-05
jpa不支持limit关键字,请问如何修改! 6 楼 ainimaomi 2014-07-22
是啊,我取到的也是同样的,没用,用select *, rand() as random from 'table' order by random limit 1是能够取到随机的。 5 楼 1511104848 2014-04-18
貌似不对吧 4 楼 Rocychen 2013-12-11
很是不错 3 楼 super-code 2013-07-21
ORDER BY RAND()能够真正产生5条不相同的数据吗? 每次查询一条,查5次能够产生5条彻底不一样的数据吗? 2 楼 scut_DELL 2013-07-04
select *, rand() as random from 'table' order by random limit 1 1 楼 wujiajun311 2012-04-17
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;
为何我取得的id是同样的啊。
List<ArticleVO> articleVOList = Lists.newArrayList(); // 经过mybatis 查找推荐文章的 id,title List<ArticleEntity> articleEntityList = articleDao.findRadomArticle(PageRequestUtils.buildSpringDataPageRequest(new PageRequest(1, 120))).getContent(); if (CollectionUtils.isNotEmpty(articleEntityList) == true) { ArticleVO articleVO; // 随机保存12条数据 Random random = new Random(); for (int i = 0; i < 12; i++) { articleVO = new ArticleVO(); ArticleEntity tempArticleEntity = articleEntityList.get(random.nextInt(articleEntityList.size())); // 一、文章实体 articleVO.setArticleEntity(tempArticleEntity); // 二、查找图片 articleVO.setImageList(articleMybatisDao.getArticleImages(tempArticleEntity.getId(), PageRequestUtils.buildMyBatisPageRequest(new PageRequest(1, 1)))); // articleVOList.add(articleVO); } // for (ArticleEntity articleEntity : articleEntityList) { // articleVO = new ArticleVO(); // // 一、文章实体 // articleVO.setArticleEntity(articleEntity); // // 二、查找图片 // articleVO.setImageList(articleMybatisDao.getArticleImages(articleEntity.getId(), // PageRequestUtils.buildMyBatisPageRequest(new PageRequest(1, // 1)))); // // // articleVOList.add(articleVO); // } } return articleVOList;