mysql order by rand() 優化方法

mysql order by rand() 優化方法 適用於領取獎品等項目
<pre>
mysql> select * from user order by rand() limit 1;
+-------+------------+----------------------------------+----------+--------------+-----------+
| id | phone | password | salt | country_code | ip |
+-------+------------+----------------------------------+----------+--------------+-----------+
| 15160 | 6549721306 | e4f302120c006880a247b652ad0e42f2 | 40343586 | 86 | 127.0.0.1 |
+-------+------------+----------------------------------+----------+--------------+-----------+
1 row in set (0.25 sec)
mysql> explain select * from user order by rand() limit 1;
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------+
| 1 | SIMPLE | user | ALL | NULL | NULL | NULL | NULL | 200303 | Using temporary; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------+
1 row in set (0.00 sec)
</pre>
根據分析結果,運行須要0.25秒,order by rand() 須要使用臨時表(Using temporary),須要使用文件排序(Using filesort),效率低下。php


改進方法
<pre>
<pre>
<?php
// 獲取總記錄數
$sqlstr = 'select count(*) as recount from user';
$query = mysql_query($sqlstr) or die(mysql_error());
$stat = mysql_fetch_assoc($query);
$total = $stat['recount'];mysql

// 隨機偏移
$offset = mt_rand(0, $total-1);sql

// 偏移後查詢
$sqlstr = 'select * from user limit '.$offset.',1';
$query = mysql_query($sqlstr) or die(mysql_error());
$result = mysql_fetch_assoc($query);fetch

print_r($result);
?>
</pre>
<pre>
mysql> select * from user limit 23541,1;
+-------+------------+----------------------------------+----------+--------------+-----------+
| id | phone | password | salt | country_code | ip |
+-------+------------+----------------------------------+----------+--------------+-----------+
| 23542 | 3740507464 | c8bc1890de179538d8a49cc211859a46 | 93863419 | 86 | 127.0.0.1 |
+-------+------------+----------------------------------+----------+--------------+-----------+
1 row in set (0.01 sec)優化

mysql> explain select * from user limit 23541,1;
+----+-------------+-------+------+---------------+------+---------+------+--------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------+
| 1 | SIMPLE | user | ALL | NULL | NULL | NULL | NULL | 200303 | NULL |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------+
1 row in set (0.00 sec)
</pre>
</pre>code

相關文章
相關標籤/搜索