国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

MySQL查詢隨機(jī)數(shù)據(jù)的4種方法和性能對比

2024-07-24 12:47:30
字體:
供稿:網(wǎng)友
下面從以下四種方案分析各自的優(yōu)缺點(diǎn)。
方案一:
復(fù)制代碼 代碼如下:
SELECT * FROM `table` ORDER BY RAND() LIMIT 0,1;

這種方法的問題就是非常慢。原因是因?yàn)镸ySQL會創(chuàng)建一張零時(shí)表來保存所有的結(jié)果集,然后給每個(gè)結(jié)果一個(gè)隨機(jī)索引,然后再排序并返回。
有幾個(gè)方法可以讓它快起來。
基本思想就是先獲取一個(gè)隨機(jī)數(shù),然后使用這個(gè)隨機(jī)數(shù)來獲取指定的行。
由于所有的行都有一個(gè)唯一的id,我們將只取最小和最大id之間的隨機(jī)數(shù),然后獲取id為這個(gè)數(shù)行。為了讓這個(gè)方法當(dāng)id不連續(xù)時(shí)也能有效,我們在最終的查詢里使用”>=”代替”=”。
為了獲取整張表的最小和最大id,我們使用MAX()和MIN()兩個(gè)聚合函數(shù)。這兩個(gè)方法會返回指定組里的最大和最小值。在這里這個(gè)組就是我們表里的所有id字段值。
方案二:
復(fù)制代碼 代碼如下:
<?php
$range_result = mysql_query( " SELECT MAX(`id`) AS max_id , MIN(`id`) AS min_id FROM `table` ");
$range_row = mysql_fetch_object( $range_result );
$random = mt_rand( $range_row->min_id , $range_row->max_id );
$result = mysql_query( " SELECT * FROM `table` WHERE `id` >= $random LIMIT 0,1 ");

就像我們剛才提到的,這個(gè)方法會用唯一的id值限制表的每一行。那么,如果不是這樣情況怎么辦?
下面這個(gè)方案是使用了MySQL的LIMIT子句。LIMIT接收兩個(gè)參數(shù)值。第一個(gè)參數(shù)指定了返回結(jié)果第一行的偏移量,第二個(gè)參數(shù)指定了返回結(jié)果的最大行數(shù)。偏移量指定第一行是0而不是1。
為了計(jì)算第一行的偏移量,我們使用MySQL的RAND()方法從0到1之間生成一個(gè)隨機(jī)數(shù)。然后我們把這個(gè)數(shù)字跟我們用COUNT()方法獲取倒的表記錄數(shù)相乘。由于LIMIT的參數(shù)必須是int型而不能是float,我們使用FLOOR()來處理結(jié)果。FLOOR()會計(jì)算小于表達(dá)式的最大值。最終的代碼就是這樣:
方案三:
復(fù)制代碼 代碼如下:
<?php
$offset_result = mysql_query( " SELECT FLOOR(RAND() * COUNT(*)) AS `offset` FROM `table` ");
$offset_row = mysql_fetch_object( $offset_result );
$offset = $offset_row->offset;
$result = mysql_query( " SELECT * FROM `table` LIMIT $offset, 1 " );

在MySQL 4.1以后我們可以使用子子查詢合并上面兩個(gè)方法:
方案四:
復(fù)制代碼 代碼如下:
SELECT * FROM `table` WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` ) ORDER BY id LIMIT 1;

這個(gè)方案跟方案二有同樣的弱點(diǎn),只對有唯一id值的表有效。
記住我們最初尋找選擇隨機(jī)行的替代方法的原因,速度!所以,這些方案的在執(zhí)行時(shí)間上的比較會怎么樣?我不會指出硬件和軟件配置或者給出具體的數(shù)字。大概的結(jié)果是這樣的:
最慢的是解決方案一(我們假定它用了100%的時(shí)間)。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 岑巩县| 桑日县| 始兴县| 株洲县| 玉屏| 聂荣县| 仪陇县| 大余县| 崇左市| 河南省| 梅州市| 聂荣县| 永兴县| 桃源县| 进贤县| 西峡县| 沈丘县| 维西| 墨脱县| 桂平市| 广平县| 新安县| 高碑店市| 乌拉特后旗| 赫章县| 兰溪市| 枝江市| 丹寨县| 道孚县| 肥乡县| 台湾省| 万荣县| 巴彦淖尔市| 汝城县| 新巴尔虎右旗| 京山县| 丹棱县| 柯坪县| 吴江市| 黄平县| 亚东县|