數據場景
一個很簡單 的業務數據表,2300W規模的數據,沒有複雜數據類型,不想分表,還需要全表遍歷
Select全表性能
- 查詢接口
@Mapper
public interface UserMapper {
@Select("SELECT * FROM loadtimeslot")
public List<Pojo> select();
}
- 性能:耗時721s,查詢效率相對較低,內存一次性增長過快,很容易撐不住
分頁查詢
- 查詢接口
@Mapper
public interface UserMapper {
@Select("SELECT * FROM loadtimeslot order by id limit #{offset},#{limit}")
public List<Pojo> selectByPage(@Param("offset") long offset,@Param("limit") int limit);
}
//遞歸查詢
private void selectData(long offset, List<Pojo> res)
{
int limit =100000;
long start = System.currentTimeMillis();
List<Pojo> data = oMapper.selectByPage(offset, limit);
res.addAll(data);
System.out.print(String.format("Load page data,offset[%d],cost[%d]ms\r\n", offset,System.currentTimeMillis()-start));
if (data.size()<limit)
return ;
else
selectData(offset+limit, res);
}
- 性能:最開始的頁碼查詢速度很快,但是越到最後查詢效率越低,第一頁需要2.4s,最後一頁全量數據需要10.5s,總耗時1452s
Line 27: Load data from db start
Line 38: Load page data,offset[0],cost[2486]ms
Line 39: Load page data,offset[100000],cost[2048]ms
Line 40: Load page data,offset[200000],cost[1974]ms
Line 41: Load page data,offset[300000],cost[2032]ms
Line 42: Load page data,offset[400000],cost[2048]ms
Line 43: Load page data,offset[500000],cost[2095]ms
Line 44: Load page data,offset[600000],cost[2297]ms
Line 45: Load page data,offset[700000],cost[2407]ms
Line 46: Load page data,offset[800000],cost[2240]ms
.
.
.
.
Line 262: Load page data,offset[22400000],cost[10708]ms
Line 263: Load page data,offset[22500000],cost[10287]ms
Line 264: Load page data,offset[22600000],cost[10153]ms
Line 265: Load page data,offset[22700000],cost[10355]ms
Line 266: Load page data,offset[22800000],cost[10210]ms
Line 267: Load page data,offset[22900000],cost[10421]ms
Line 268: Load page data,offset[23000000],cost[10523]ms
Line 269: Load page data,offset[23100000],cost[9231]ms
Line 270: Load end:[1451794]ms
- 分析原因:limit 1000,100,意思是掃描滿足條件的1000+100 行,丟棄掉前邊的1000行,返回最後的100行,當偏移量足夠大的時候,每次檢索都要執行offset的偏移量處理,性能肯定會越來越差
分頁查詢優化
- 根據where條件跳過offset的偏移量處理
@Select("SELECT * FROM loadtimeslot where id>#{offset} order by id asc limit #{limit}")
public List<Pojo> selectByPage(@Param("offset") long offset,@Param("limit") int limit);
- 性能: 分頁查詢單次時間消耗不隨offset增大而增多,最後一次10000W條查詢耗時2s,總耗時494s,相比之前的分頁查詢快了將近5倍
Line 27: Load data from db start
Line 38: Load page data,offset[0],cost[4707]ms
Line 39: Load page data,offset[100000],cost[3254]ms
Line 40: Load page data,offset[200000],cost[2251]ms
Line 41: Load page data,offset[300000],cost[2064]ms
Line 42: Load page data,offset[400000],cost[2034]ms
Line 43: Load page data,offset[500000],cost[1971]ms
Line 44: Load page data,offset[600000],cost[2100]ms
Line 45: Load page data,offset[700000],cost[2146]ms
Line 46: Load page data,offset[800000],cost[1973]ms
.
.
.
.
.
Line 264: Load page data,offset[22600000],cost[1925]ms
Line 265: Load page data,offset[22700000],cost[2079]ms
Line 266: Load page data,offset[22800000],cost[2015]ms
Line 267: Load page data,offset[22900000],cost[2175]ms
Line 268: Load page data,offset[23000000],cost[2065]ms
Line 269: Load page data,offset[23100000],cost[2015]ms
Line 270: Load page data,offset[23200000],cost[1204]ms
Line 271: Load end:[494943]ms