博客后台接口优化-访问记录📜
前言
博客地址:ZY知识库 · ZY - Home Page (pljzy.top) www.pljzy.top
一直没有更新文章了,曾梦想着每周更新一篇文章。直到上班之后才知道,根本不想写。我现在的状态就是下班回家吃完晚饭刷会视频看会剧,洗个澡儿,睡觉。下班之后根本不想写代码😮💨。
如果是双休的话我可能会一周一更,但是单休的程序员,我真的一点动力都没有,已经被资本家压榨得干干净净了。
回到正题,虽然文章没有更新,但是博客还是有收到各大搜索引擎的爬虫(除开百度,因为博客备案到期了,我换到香港服务器了,百度不会爬取),导致访问记录持续增加,现在访问记录已经有172875条记录了
问题解析
博客很多地方的分页都是用的一款组件,叫做X.PagedList
组件,这款组件使用起来还是方便的,但是他是将数据全部查询出来,加载到内存中进行分页,相当于我从数据库一次拿了172875条数据出来,然后进行分页。如果不搭配缓存的话,这样分页的效率是很低的。
抛开网络传输,本地测试看看接口响应需要多久,本地跑只要1.48秒,线上跑需要花7.99秒
本地
线上
那么就针对本地1.48秒进行优化。
解决办法
既然一次性去10万条数据慢,那我何不在查询sql的时候就分页呢。所以当我们去向数据库拿取数据的时候就只拿取当前页的数据,具体实现如下:
原本写法
public IPagedList<VisitRecord> GetPagedList(VisitRecordQueryParameters param)
{
var querySet = _myDbContext.visitRecords.ToArray();
// 搜索
if (!string.IsNullOrEmpty(param.Search))
{
querySet = querySet.Where(a => a.RequestPath.Contains(param.Search)).ToArray();
}
querySet = querySet.OrderByDescending(a => a.Id).ToArray();
return querySet.ToList().ToPagedList(param.Page, param.PageSize);
}
生成的sql语句,放到数据库执行如下:
修改写法
public async Task<(List<VisitRecord>, PaginationMetadata)>GetPagedList(VisitRecordQueryParameters param)
{
var querySet = _myDbContext.visitRecords.AsQueryable();
// 搜索
if (!string.IsNullOrEmpty(param.Search))
{
querySet = querySet.Where(a => a.RequestPath.Contains(param.Search));
}
var data = await querySet
.OrderByDescending(a => a.Id)
.Skip((param.Page - 1) * param.PageSize)
.Take(param.PageSize)
.ToListAsync();
var pagination = new PaginationMetadata()
{
PageNumber = param.Page,
PageSize = param.PageSize,
TotalItemCount = await querySet.CountAsync()
};
return (data, pagination);
}
修改后生成的sql语句如下,在数据库分页。
优化对比
可以看到还是优化了挺多的。
结尾
当数据量到达百万级,又该如何优化呢🤔
如果大家有更好的办法,可以评论私信~
如果不想自己写返回分页数据的类,可以使用CodeLab.Share
,Nuget包。