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;