从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语句结合时,有些变化没有被观察到。往后注意级联查询时用左连接,能避免类似的错误出现。