一、最初版本是这个
SELECT * FROM products WHERE category_id = '3' ORDER BY RAND() LIMIT 3
或者在mssql server 上是
SELECT * FROM Northwind.customers Orders ORDER BY NEWID()
这种方法是要对整个表扫描,然后产生一个计算列再排序的,效率相当低,经kolidon测试,十万量级数据库中耗时数十秒。

二、有人给出了这个版本,但一次只能选一条记录
SELECT *
FROM `table`
WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) 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;
这个速度很牛,实测中10万量级数据小于1ms

三、那么,多条记录有人的办法是直接查10次
也不错,大约在10ms左右。
但考虑这种情况——随机列出一些记录往往是页面的某一个模块,占用10ms已经太多。

那么,用这种办法:
1. 若需要选出n条记录,先选出指定数据表最大值及最小值,根据最大及最小值生成2n或3n个范围内随机整数(根据表内记录排列稀疏程序而定),连接成逗号分隔之id串;
2. 采用where id in (ids)查询。
在kolidon的zhonghuayixue.com中,这个功能(列出随机图片、随机视频、随机电子书),三个模块,总耗时12ms以内。

这是从30-10,效率提升3倍的办法。