[MySQL] LIMIT 分頁優化

背景:LIMIT 0,20 這種分頁方式,隨着 offset 值的不斷增大,當達到百萬級時,一條查詢就須要1秒以上,這時能夠藉助索引條件的查詢來優化。html

SQL:select * from member where status = 1 limit 0,20;  改寫  select * from member where id >= 1 and status = 1 limit 20;優化

代碼片斷:this

/**
 * limit 分頁優化
 * @author ercom
 */
$startTime = time();
$condition = [ ['status', '=', 1], ['platform', '=', 1], ]; $count = Member::query() ->where($condition) ->count('id'); $pageSize = 20; $pageNum = ceil($count / $pageSize); $startMemberId = 1; for ($i = 1; $i <= $pageNum; $i++) { $condition = [ ['id', '>=', $startMemberId], ['status', '=', 1], ['platform', '=', 1], ]; $results = Member::query() ->where($condition) ->orderBy('id', 'asc') ->limit($pageSize) ->get(); if ($results->isNotEmpty()) { $memberArr = $results->toArray(); dispatch(new TransferMemberJob($memberArr)); $startMemberId = max(array_column($memberArr, 'id')) + $pageSize; } else { $startMemberId = $startMemberId + $pageSize; } $this->info(sprintf('page=%s, startMemberId=%s', $i, $startMemberId)); }

  $endTime = time();spa

 
 

  $seconds = $endTime - $startTime;
  $hours = sprintf('%.2f', $seconds/3600);
  $rps = sprintf('%.2f', $count/$seconds);
  $qps = sprintf('%.2f', $pageNum/$seconds);code

$this->info(sprintf('All finished, %s / %s, total %s rows, cost %s hours, %s rows/s, %s query/s', date('Y-m-d H:i:s', $startTime), date('Y-m-d H:i:s', $endTime), $count, $hours, $rps, $qps));

 

Link:http://www.javashuo.com/article/p-osufbczv-dx.htmlorm

相關文章
相關標籤/搜索