要做一个分页,发现前端页面卡死,原因因为数据量太大,百万级数据,经过优化查询方法,已经没问题了,页面数据都可以快速展示
1、先来看一组让页面卡死的代码:
def aaa(request): page = request.GET.get('page') start = (int(page) - 1) * 15 + 1 end = start + 15 all_arts = Article.objects.values("id","title").filter(type="python") paginator = Paginator(all_arts, 15) arts = all_arts[start:end] product_list = paginator.page(page)get('page') start = (int(page) - 1) * 15 + 1 end = start + 15 all_arts = Article.objects.values("id","title").filter(type="python") paginator = Paginator(all_arts, 15) arts = all_arts[start:end] product_list = paginator.page(page)
page:前端传来的页码参数
start:每页显示15条数据,设置切片起始位置
end : 设置切片结束位置
all_arts : 找出类型为python的所有数据,查找字段为id和title
paginator:分页15条,返回分页
以上查询,数据量小的时候可能感觉不出来问题,当数据量大的时候,比如我这里举个例子,Article有100万条数据,查询type=python的大概有10万条数据,这种写法查询性能极差,原因在于我查的时候,没有用索引来查,程序就卡在了这个地方,我的索引[start,end]用在了查询后的切片上面,但此时的切片,起不到什么提高查询效率的作用
all_arts = Article.objects.values("id","title").filter(type="python")"id","title").filter(type="python")那么该怎么查,才能最大提高效率?原生SQL中,我们可以适用limit来进行查询,举个例子,18万数据,进行查询,我就不截图了,把查询运行时间说下
不用limit进行查询:16秒
select id,title from aaa where type='python';from aaa where type='python';用limit进行查询:0.062秒
select id,title from aaa where type='python' limit 0,20;0,20;两种方式查询的数据取到的数据不一样,前者取全量type="python"数据,用时16秒,后者通过加限制条件,从第一条开始取,取20条,用时0.062秒
那么我们django分页也可以按照这种类似limit的方式来进行查询,前端请求某一页的时候,我们只查那一页的数据,不全量返回数据,用什么查什么,页面就不会卡死,而我上面分享的卡死的方法,是查的全量数据,页面容易卡死
基于此,开始进行代码优化,在django中,limit的实现是通过切片来完成的,奉上代码,其实我们只要将切片[start:end]加在filter查询或者all查询后面即可,优先查我们需要的15条数据
all_arts = Article.objects.filter(btype=stype)[start:end].values("id","title")start:end].values("id","title")另外,django orm功能强大,我也是遇到什么需求,就去着重学下,另外我还需要查询全量数据的长度,该怎么查?
这样写行不行?
len(Article.objects.all())all())没问题可以,只不过还是牵涉到查询效率问题,SQL查询是一门精妙的学问,怎么查才能最快的查到我们想要的结果,对于查询个数,我们写SQL语句一般可以这样写,用count方法
select count(*) from aaa;count(*) from aaa;
那么在django中也对应的有count方法
Article.objects.all().count().objects.all().count()同样是查询,平时我们接触不到大量数据,可能我们怎么写都可以快速获取想要的结果,感受不到查询效率问题,但是当我们数据量大到一定程度,SQL查询则必须研究,一定会有更好的查询方法,最近通过这些简单的例子,对SQL查询也有了进一步了解
另外,有个小问题,也是我最近在研究的问题,我这里有个数据库为3GB的表,大概8万条数据,用pandas进行read_sql读取,非常慢,12GB的内存也快满了,无法进行后续数据处理操作,该如何进行读取?欢迎有知道的大佬留言
python爬虫人工智能大数据公众号