在平时开发过程中,数据量不超过1W条的,通常执行随机查询是通过对order进行rand操作的进行的。但是随着数据量的增加,rand严重制约了整站的访问速度。
这是什么原因造成的呢?mysql官方的说话是rand函数在order中会被反复扫描多次,造成性能急剧下降。
网友的的解决办法最多的就是通过对min和max之间的ID进行随机,这样就存在一个问题,如果是自增主键,那么某条数据被删除,那么就可能随机到一条已经被删除的内容,展现出来的时候就达不到预期的效果。
我的解决办法是先索引所有有效内容的ID,这个查询很快。迅速完成,即使数据量在百万级。得到的ID数组,经过遍历后将原数组转换成一个键名和键值相同的数组。使用array_rand函数随机产生需要的键名,再通过键名去查询数据库。这样通过有限的查询获得100%存在的数据。
代码:
$map['art_status']=['=',0];//文章状态为发布
$art=Db::name('article')->field('id')->where($map)->select();
foreach ($art as $key => $value) {
$arr[$value['id']]=$value['id'];//构造文章ID为键名的数组
}
$ar=array_rand($arr,$num);//随机元素键名
return $ar;