MysSQL如何高效地随机读取数据
MysSQL如何高效地随机读取数据
现在有个需求,需要从mysql中随机读取出100条认证企业的数据,每一次读取的数据均不同?
下面两表中, member_verify 中有约400W数据,company中有约8W条
可能很多人会联想到order by rand()这样来实现,具体语句如下:
1 SELECT c.user_id, c.company_name 2 FROM `jc_company` c 3 LEFT JOIN `jc_member_verify` v ON c.user_id = v.user_id 4 WHERE v.company_status = 2 5 AND c.province_id = 0 6 GROUP BY c.company_name 7 ORDER BY rand() 8 LIMIT 1000
我们来用explain看下上面语句使用索引的情况:
由上面的结果可以分析,order by rand() 导致了mysql使用了外部排序,sql效率非常低
优化方案的方案有很多,比如放到redis缓存,每次从redis缓存读取,下面是其中一种:
1)不做连接查询,先到member_verify通过company_status筛选出满足条件的数据,再到company中去查询最后要查询数据
2)每次展示N条,取100页的数据,通过随机生成1-100的页码,取到第N页的数据
1 $countQuery= $this->select(['id','user_id']) ->where('company_status', 2); 2 3 $count= $this->select(['id','user_id']) ->where('company_status', 2)->count();
1 public function cleaningJob($pageSize): array 2 { 3 4 $randPage = 1; 5 if ($count > $pageSize) { 6 $endNum = (int)ceil($count / $pageSize); 7 $randPage = random_int(1, ($endNum > 100 ? 100 : $endNum)); 8 } 9 10 $offset=(randPage-1)*pageSize; 11 12 $query = $countQuery->select(['title', 'id', 'province_id', 'city_id']) 13 ->limit($offset, $pageSize); 14 15 }
然后通过company的唯一键user_id 去company查询出company_name