一、最初版本是这个
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倍的办法。

关注WEB应用系统架构,侧重效能、可用性研究。欢迎访问treeber.com查看本站整理自网络的非原创精华(筹建中)。
廣告筆
April 22nd, 2009 at 4:06 pm
還有詳細一點嗎
廣告扇
April 22nd, 2009 at 4:07 pm
不明白