一、隨機查詢一條資料
方法一:select* from`table`orderbyrand() limit 1
評價:不建議使用,效率非常低,官方文件中進行說明:order by和rand()連用,會多次掃描表,導致速度變慢。
方法二:select* from`table`
whereid>= (selectfloor(rand()* (selectmax(id)from`table`)))
orderbyidlimit1;
解釋:selectmax(id)from`table` 這句話查詢出最大的id值
selectfloor(rand()* (selectmax(id)from`table`)) 這句獲取一個小於max(id)的隨機數
whereid>= (selectfloor(rand()* (selectmax(id)from`table`))) 這句話篩選出所有的大於生成隨機數的id的行
然後最後就把大於這個隨機id的行查詢出來,然後按照id排序,選擇第一個,就相當與獲取了所有行中隨機的一行。
評價:有問題,如果id不是從0開始的話,比如從10000開始自增,那麼 selectfloor(rand()* (selectmax(id)from`table`)) 得到的將是會喲很大概率得到小於10000的值,經過where限定的查詢結果將會是所有的查詢結果的機率變大,最後limit 1獲取的是第一行資料的機率變高。
方法三:select* from`table`
whereid>= (selectfloor(rand()* ((selectmax(id)from`table`)-(selectmin(id)from`table`))+ (selectmin(id)from`table`)))orderbyidlimit1;
方法四:select*
from`table`ast1join(selectround(rand()* ((selectmax(id)from`table`)-(selectmin(id)from`table`))+
(selectmin(id)from`table`))asid)ast2
wheret1.id>= t2.id
orderbyt1.idlimit1;
評價:解決了方法二中max(id)的問題,rand()* ((selectmax(id)from`table`)-(selectmin(id)from`table`))+ (selectmin(id)from`table`)可以獲取max(id)和min(id)中的隨機數。
方法四要比方法三稍快一點, 這篇部落格指出,15w條資料前者花費時間0.147433 秒,後者花費時間0.015130 秒。
以上解決方案都預設有一個不重複的數字欄位,其實現在很多表的設計都是以一個自增段作為主鍵,當然還有一些是以uuid作為主鍵的,而沒有數字鍵,這樣的話,可以用mysql的函式將uuid的字串轉換成數字。而且還有一個問題,如果id欄位的數字分佈不均勻的話(比如按照1,4,5,6,7,8,45這樣分佈),也會造成隨機查詢的不合理,但是這裡就不討論那麼複雜的問題了。
二、隨機查詢多條資料
方法一:把隨機查詢一條資料的limit 1修改成limit 5
評價:這樣獲取的資料會是連續的。
方法二:
select*
from`table`ast1join(
selectround(rand()* ((selectmax(id)from`table`)-(selectmin(id)from`table`))+(selectmin(id)from`table`))asid
from `table` limit 50)ast2on t1.id=t2.id
orderbyt1.idlimit1;
解釋:selectround(rand()* ((selectmax(id)from`table`)-(selectmin(id)from`table`))+(selectmin(id)from`table`))asid
from `table` limit 50)這樣會獲取50個隨機數字,然後on t1.id=t2.id會挑選出不大於50行的隨機資料,然後取5條就好了。
方法一:select* from`table`orderbyrand() limit 1
評價:不建議使用,效率非常低,官方文件中進行說明:order by和rand()連用,會多次掃描表,導致速度變慢。
方法二:select* from`table`
whereid>= (selectfloor(rand()* (selectmax(id)from`table`)))
orderbyidlimit1;
解釋:selectmax(id)from`table` 這句話查詢出最大的id值
selectfloor(rand()* (selectmax(id)from`table`)) 這句獲取一個小於max(id)的隨機數
whereid>= (selectfloor(rand()* (selectmax(id)from`table`))) 這句話篩選出所有的大於生成隨機數的id的行
然後最後就把大於這個隨機id的行查詢出來,然後按照id排序,選擇第一個,就相當與獲取了所有行中隨機的一行。
評價:有問題,如果id不是從0開始的話,比如從10000開始自增,那麼 selectfloor(rand()* (selectmax(id)from`table`)) 得到的將是會喲很大概率得到小於10000的值,經過where限定的查詢結果將會是所有的查詢結果的機率變大,最後limit 1獲取的是第一行資料的機率變高。
方法三:select* from`table`
whereid>= (selectfloor(rand()* ((selectmax(id)from`table`)-(selectmin(id)from`table`))+ (selectmin(id)from`table`)))orderbyidlimit1;
方法四:select*
from`table`ast1join(selectround(rand()* ((selectmax(id)from`table`)-(selectmin(id)from`table`))+
(selectmin(id)from`table`))asid)ast2
wheret1.id>= t2.id
orderbyt1.idlimit1;
評價:解決了方法二中max(id)的問題,rand()* ((selectmax(id)from`table`)-(selectmin(id)from`table`))+ (selectmin(id)from`table`)可以獲取max(id)和min(id)中的隨機數。
方法四要比方法三稍快一點, 這篇部落格指出,15w條資料前者花費時間0.147433 秒,後者花費時間0.015130 秒。
以上解決方案都預設有一個不重複的數字欄位,其實現在很多表的設計都是以一個自增段作為主鍵,當然還有一些是以uuid作為主鍵的,而沒有數字鍵,這樣的話,可以用mysql的函式將uuid的字串轉換成數字。而且還有一個問題,如果id欄位的數字分佈不均勻的話(比如按照1,4,5,6,7,8,45這樣分佈),也會造成隨機查詢的不合理,但是這裡就不討論那麼複雜的問題了。
二、隨機查詢多條資料
方法一:把隨機查詢一條資料的limit 1修改成limit 5
評價:這樣獲取的資料會是連續的。
方法二:
select*
from`table`ast1join(
selectround(rand()* ((selectmax(id)from`table`)-(selectmin(id)from`table`))+(selectmin(id)from`table`))asid
from `table` limit 50)ast2on t1.id=t2.id
orderbyt1.idlimit1;
解釋:selectround(rand()* ((selectmax(id)from`table`)-(selectmin(id)from`table`))+(selectmin(id)from`table`))asid
from `table` limit 50)這樣會獲取50個隨機數字,然後on t1.id=t2.id會挑選出不大於50行的隨機資料,然後取5條就好了。
mysql實現高效率隨機查詢多條資料
mysql實現高效率查詢多條資料 sql語句 select from account as t1 join select round rand select max sys account id from account select min sys account id from account ...
MYSQL的隨機查詢的實現方法
mysql的隨機抽取實現方法。舉個例子,要從tablename表中隨機提取一條記錄,大家一般的寫法就是 select from tablename order by rand limit 1。但是,後來我查了一下mysql的官方手冊,裡面針對rand 的提示大概意思就是,在order by從句裡面不...
MYSQL的隨機查詢的實現方法
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.i...