從Mysql某一表中隨機讀取n條數據的SQL查詢語句

若要在i?≤?R?≤?j?這個范圍得到一個隨機整數R?,需要用到表達式?FLOOR(i?+ RAND() * (j?–?i?+ 1))。例如, 若要在7?到?12?的范圍(包括7和12)內得到一個隨機整數,?可使用以下語句:

SELECT FLOOR(7 + (RAND() * 6));

以上摘抄自MySQL手冊

?

從 Mysql 表中隨機讀取數據不難,方法還挺多的,但是如果要考慮效率,得到一個快速的高效率的方法,那就不是一件簡單的事情了(至少對我來說不簡單)。

隨機獲得Mysql數據表的一條或多條記錄有很多方法,下面我就以users(userId,userName,password……)表(有一百多萬條記錄)為例,對比講解下幾個方法效率問題:


  1. select * from????? users order by rand() LIMIT 1
    執 行該sql語句,老半天沒有反應,最后被迫手動停止執行,怎個傷人了得啊!后來我查了一下MYSQL手冊,里面針對RAND()的提示大概意思就是,在 ORDER BY從句里面不能使用RAND()函數,因為這樣會導致數據列被多次掃描,導致效率相當相當的低!效率不行,切忌使用!
  2. SELECT * FROM????? users? AS t1? JOIN (SELECT ROUND(RAND() * ((SELECT MAX(userId)????? FROM `users`)-(SELECT MIN(userId) FROM users))+(SELECT MIN(userId) FROM????? users)) AS userId) AS t2 WHERE t1.userId >= t2.userId ORDER BY????? t1.userId LIMIT 1
    執行該sql語句,用時0.031s,效率沒說的,相當的給力!心里那個爽啊,緊接著,我把”LIMIT????? 1“改為了”LIMIT 100“ 隨機取一百條記錄,用時0.048,給力吧。可是就在此時問題出現了,發現結果好像不是隨機的?為了驗證結果,又執行了N次,真不是隨機的, 問題出現在”ORDER BY t1.userId“這里,按userId排序了。隨機取一條記錄還是不錯的選擇,多條就不行了啊!
  3. SELECT * FROM????? users WHERE userId >= ((SELECT MAX(userId) FROM users)-(SELECT????? MIN(userId) FROM users)) * RAND() + (SELECT MIN(userId) FROM users)?????? LIMIT 1
    執行該sql語句,用時0.039s,效率太給力了!接著我就把”LIMIT 1“改為了”LIMIT 10000“,用時0.063s。經過多次驗證,哥對燈發誓,結果肯定是隨機的!
    結論:隨機取一條或多條記錄,方法都不錯!
  4. 通過sql獲得最大值和最小值,然后通過php的rand生成一個隨機數randnum,再通過SELECT * FROM users WHERE userId >= randnum LIMIT 1,獲得一條記錄效率應該還可以,多條應該就不行了。

    結論:方法1效率不行,切忌使用;隨機獲得一條記錄,方法2是相當不錯的選擇,采用JOIN的語法比直接在WHERE中使用函數效率還是要高一些的,不過方法3也不錯;隨機獲得多條記錄,方法3沒說的!

從Mysql某一表中隨機讀取n條數據的SQL查詢語句其他相關資料


SQL語句先隨機好ID序列,用 IN 查詢(飄易推薦這個用法,IO開銷小,速度最快):
$sql="SELECT MAX(id),MIN(id) FROM content";
$result=mysql_query($sql,$conn);
$yi=mysql_fetch_array($result);
$idmax=$yi[0];
$idmin=$yi[1];
$idlist='';????
for($i=1;$i<=20;$i++){????
if($i==1){ $idlist=mt_rand($idmin,$idmax); }????
else{ $idlist=$idlist.','.mt_rand($idmin,$idmax); }????
}??
$idlist2="id,".$idlist;
$sql="select * from content where id in ($idlist) order by field($idlist2) LIMIT 0,12";
$result=mysql_query($sql,$conn);
$n=1;
$rnds='';
while($row=mysql_fetch_array($result)){
$rnds=$rnds.$n.". <a href='show".$row['id']."-".strtolower(trim($row['title']))."'>".$row['title']."</a><br />\n";
$n++;
}
800萬數據隨機取一條的牛方法
mysql> select FLOOR(id*rand()) from test_rand where id=(select MAX(id) from test
_rand);
+------------------+
| FLOOR(id*rand()) |
+------------------+
| 5225551 |
+------------------+
1 row in set (0.00 sec)

語句簡單,速度慢的方法
SELECT * FROM table_name ORDER BY rand() LIMIT 5;

語句復雜,速度快的方法
SELECT * FROM table_name AS r1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM table_name)) AS id) AS r2 WHERE r1.id >= r2.id ORDER BY r1.id ASC LIMIT 5;


cjc注: ... AS id) AS t2 這里的 id, 也許該換成id2, 后面 WHERE t1.id >= t2.id 改成? WHERE t1.id >= t2.id2

摘自:?http://www.dayanmei.com/blog.php/ID_203.htm

******************************************************************************************


Discuz中,隨機讀取論壇的幾個連續主題:

PHP里調用:
$s = "SELECT tid, fid, subject FROM {$tablepre}threads AS r1 JOIN (SELECT ROUND(RAND()*(SELECT MAX(tid) FROM {$tablepre}threads)) AS id) AS r2 WHERE (fid=13) and (r1.tid >= r2.id) ORDER BY r1.tid LIMIT 6";

$query = $db->query($s);
???????

phpMyAdmin 中測試語句:
SELECT tid, fid, subject FROM cdb_threads AS r1 JOIN (SELECT ROUND(RAND()*(SELECT MAX(tid) FROM cdb_threads)) AS id) AS r2 WHERE (fid=13) and (r1.tid >= r2.id) ORDER BY r1.tid LIMIT 6

注意: 不可刪除 order by r1.tid, 否則總會固定出現最初的2行數據?


******************************************************************************************

另一文章里使用了MIN()的版本:

通用語句:


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;


cjc注: ... AS id) AS t2 這里的 id, 也許該換成id2, 后面 WHERE t1.id >= t2.id 改成? WHERE t1.id >= t2.id2

Discuz 語句:

SELECT tid, fid,subject
FROM `cdb_threads` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(tid) FROM `cdb_threads`)-(SELECT MIN(tid) FROM `cdb_threads`))+(SELECT MIN(tid) FROM `cdb_threads`)) AS id) AS t2
WHERE t1.tid >= t2.id and fid=13 ORDER BY t1.tid LIMIT 5;


or

$s = "SELECT * FROM {$tablepre}threads AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(tid) FROM {$tablepre}threads)-(SELECT MIN(tid) FROM {$tablepre}threads))+(SELECT MIN(tid) FROM {$tablepre}threads)) AS id) AS t2 WHERE (t1.tid >= t2.id) and (fid=13) ORDER BY t1.tid LIMIT 6";

$query = $db->query($s);
???????

cjc注: MIN(tid) 得到的通常是1, 所以加上MIN()的計算,不一定有必要.



***************************? 全文轉貼如下 ******************************************************
原文網址:?http://jnote.cn/blog/mysql/mysql-rand-efficiency.html

mysql使用rand隨機查詢記錄效率測試 - 八月 8, 2007 | Posted by 老蔣

一直以為mysql隨機查詢幾條數據,就用

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()來隨機獲取數據。

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;


最后在php中對這兩個語句進行分別查詢10次,
前者花費時間 0.147433 秒
后者花費時間 0.015130 秒
看來采用JOIN的語法比直接在WHERE中使用函數效率還要高很多。
此方法limit如果大于1,返回的結果會是連續的記錄。

?

轉載于:https://www.cnblogs.com/carlos-liye/p/6681287.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/253841.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/253841.shtml
英文地址,請注明出處:http://en.pswp.cn/news/253841.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于MTD的NAND驅動開發(二)

基于MTD的NAND驅動開發(二) 基于MTD的NAND驅動開發(三) http://blog.csdn.net/leibniz_zsu/article/details/4977853 http://blog.csdn.net/leibniz_zsu/article/details/4977869 四、基于MTD的NAND 驅動架構 1 、platform_device 和platform_driver 的定義和注冊 對于我們的…

靜態時序分析——Data to data check

setup和hold的檢查也有可能發生在任意兩個數據端口&#xff0c;其中不包括時鐘端口。 我們將其中一個端口&#xff08;pin&#xff09;設置為約束端口&#xff08;constrainted pin&#xff09;&#xff0c;就像觸發器中的數據端口&#xff1b;將另一個一個端口&#xff08;pin…

開源數據庫中間件-MyCa初探與分片實踐

如今隨著互聯網的發展&#xff0c;數據的量級也是撐指數的增長&#xff0c;從GB到TB到PB。對數據的各種操作也是愈加的困難&#xff0c;傳統的關系性數據庫已經無法滿足快速查詢與插入數據的需求。這個時候NoSQL的出現暫時解決了這一危機。它通過降低數據的安全性&#xff0c;減…

【JAVA設計模式】外觀模式(Facade Pattern)

一 定義 為子系統中的一組接口提供一個一致的界面。Facade模式定義了一個高層的接口&#xff0c;這個接口使得這一子系統更加easy使用。二 案例 一個子系統中擁有3個模塊。每一個模塊中都有3個方法。當中一個為client調用方法&#xff0c;其它兩個則為各子模塊間互相調用方法…

return的用處

#include "stdio.h" main() {int a,b1,c0;for(a1;a<5;a){ cca;}printf("%d",c);return ;printf("hello word"); } 輸出結果是10并沒有hello word&#xff1b;return將不會執行下面的語句。轉載于:https://www.cnblogs.com/doublekai/p/6148…

靜態時序分析——Clock Gating check

門控時鐘是RTL級進行低功耗設計的最常用方法&#xff0c;能夠有效降低動態功耗。在實際使用中&#xff0c;一般用ICG&#xff08;集成門控時鐘單元&#xff09;來完成clock gating。ICG電路和時序如下&#xff1a; 通常來說&#xff0c;工藝庫已經集成了ICG&#xff0c;在做門控…

U-boot中TFTP 解釋

http://www.cnblogs.com/heaad/archive/2009/08/10/1542538.html

BlackHat Arsenal USA 2018 ToolsWatch黑客工具庫

原文鏈接&#xff1a;https://medium.com/hack-with-github/black-hat-arsenal-usa-2018-the-w0w-lineup-7de9b6d32796 Black Hat Arsenal USA 2018?—?The w0w lineup After the huge success of Black Hat Arsenal USA 2017, toolswatch has now announced the list of too…

SOA是什么

SOA是什么&#xff1f; SOA是面向服務的架構&#xff0c;是一個組件模型&#xff0c;它將應用程序的不同功能單元&#xff08;稱為服務&#xff09;通過這些服務之間定義良好的接口和契約聯系起來。接口是采用中立的方式進行定義的&#xff0c;它獨立于實現服務的硬件平臺、操作…

redis 優化

系統優化echo "vm.overcommit_memory1" > /etc/sysctl.conf 0&#xff0c; 表示內核將檢查是否有足夠的可用內存供應用進程使用&#xff1b;如果有足夠的可用內存&#xff0c;內存申請允許&#xff1b;否則&#xff0c;內存申請失敗&#xff0c;并把錯誤返回給應…

IC設計常見設計思想

速度與面積互換原則 所謂速度&#xff0c;是指整個工程穩定運行所能夠達到的最高時鐘頻率&#xff0c;它不僅和電路內部各個寄存器的建立時間、保持時間以及外部器件接口的各種時序要求有關&#xff0c;而且還和兩個緊鄰的寄存器間的邏輯延時&#xff0c;走線延時有關。所謂面…

DM365 u-boot啟動分析

http://www.61ic.com/Article/DaVinci/DM644X/201009/27429.html

(十三)Hibernate高級配置

配置數據庫連接池 配置C3P0連接池。先導入c3p0包。然后在hibernate.cfg.xml文件中 &#xff0c;使用下面代碼配置連接池<property name"hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>可以通過下面的…

eclipse中如何配置tomcat

1.打開eclipse上面的Windows選項&#xff0c;選擇Preferences>Server>Runtime Environments>Add 2.選擇你電腦中安裝的tomcat的版本我的是8所以我選的是Apache Tomcat v8.0 3,Next>Browse選擇Tomcat的安裝目錄&#xff0c;選擇jdk 4.Finish>OK tomcat配置完成。…

jsp調試小技巧

console.log($("#toolbar")); 打印對象可知道這個對象的參數信息轉載于:https://www.cnblogs.com/chenweida/p/6149342.html

數字IC驗證學習(一)

一、數據類型 1、logic logic類型只能有一個驅動。使用wire和reg的地方均可使用logic&#xff0c;但如雙向總線等有多個驅動的地方&#xff0c;則不可使用logic。 2、二值邏輯 對于二值邏輯變量與DUT中的四值邏輯變量連接時&#xff0c;如果DUT中產生了X和Z&#xff0c;會被…

SecureCRT 配置文件中 找密碼

打開本地電腦如下路徑 C:\Users\XXX\AppData\Roaming\VanDyke\Config\Sessions 找到配置文件。 運行命令&#xff1a;python SecureCRTDecrypt.py [配置文件名稱] 例如&#xff1a;python SecureCRTDecrypt.py 192.168.1.249.ini ssh root192.168.1.249 # 123456 即可得到密…

刷題比賽

題目描述 給你四個數組A,B,C,D. 給出每個數組的初始值A[1] 1, B[1] 1, C[1] 1, D[1] 1 , A[2] 3, B[2] 3, C[2] 3, D[2] 3; 有以下的遞推公式: (1) a[k2]p* a[k1]qa[k]b[k1]c[k1]r k^2t * k1d[k]; (2)b[k2]u* b[k1]vb[k]a[k1]c[k1]w^kd[k]; (3)c[k2]x c[k1]yc[k]a[k1]b[…

自動化測試用例設計原則

自動化測試用例設計原則&#xff1a;每一個用例 都是一個閉合的業務操作。用例之間要保持獨立 &#xff0c;不要有操作上的依賴關系&#xff0c;就算有也是測試數據上的依賴。第二個用例 依賴第一個用例產生的數據。轉載于:https://www.cnblogs.com/yyjiangnan/p/6149430.html