数据库随机请求表中任意一行优化(使用rand函数)

从2500多行的表中随机取一行,使用rand函数:

SELECT * FROM tbl_nichuiniu_article  where Category='z1' ORDER BY  RAND()  LIMIT 1;

查询结果显示扫表两遍,order by rand() 需要使用临时表(Using temporary),需要使用文件排序(Using filesort),效率低下,查询时间800毫秒

网上找了个方法优化后,10毫秒,性能显著提升

SELECT * FROM tbl_nichuiniu_article 
WHERE Category='z1' and id >= (SELECT floor( RAND() * ((SELECT MAX(id) FROM tbl_nichuiniu_article)-(SELECT MIN(id) FROM tbl_nichuiniu_article)) + (SELECT MIN(id) FROM tbl_nichuiniu_article)))  
ORDER BY id LIMIT 1; 

0602更新
实际使用一段时间上面的sql后,发现每次随机请求到的ID都是偏小的,随机的区间只有总数的前10%。于是再次更新sql:

SELECT * FROM tbl_nichuiniu_article AS t1 JOIN (
SELECT floor( RAND() * ((SELECT MAX(id) FROM tbl_nichuiniu_article)-(SELECT MIN(id) FROM tbl_nichuiniu_article)) + 
(SELECT MIN(id) FROM tbl_nichuiniu_article)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id ASC LIMIT 1;

上一条没使用左连接,分析语句都正常,如下可获得一个随机数:

SELECT floor( RAND() * ((SELECT MAX(id) FROM tbl_nichuiniu_article)-(SELECT MIN(id) FROM tbl_nichuiniu_article)) + 
(SELECT MIN(id) FROM tbl_nichuiniu_article))

但是联合成一整个语句查询时,随机到的数字却很小。
原因是上面的sql查询出来的结果实际上是作为一张表。
使用下面的语句id>= 对应的应该是一个字段,而不是一张表。

SELECT * FROM tbl_nichuiniu_article WHERE Category='z1' and id >= 

所以如果要对应一张查询出来的新表,就需要使用左连接。

0602再次更新
最开始的用法语句是没有报错的,出问题的还是随机数生成的过程与select语句结合时,有些变化没有被观察到。往后注意级联查询时用左连接,能避免类似的错误出现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值