MYSQL的隨機查詢的實現方法

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;
相關文章
相關標籤/搜索