数据库:django ORM 如何处理 N+1 查询
数据库 N+1 查询是个常见的问题,简单描述场景如下
基本场景
class Category(models.Model):
name = models.CharField(max_length=30)
class Article(models.Model):
title = models.CharField(max_length=30)
body = models.TextField()
category = models.ForeignKey(Category)
time = models.DateTimeField()
#----列表页模板{% for a in Article.objects.all %}
{{ a.title }}
{{ a.category.name }}
{% endfor %}
在生成列表页面时,首先执行一次
select * from article limited 0,N
然后逐条获取 category.name,又需要执行 N 次
select name from category where id = category_id
所以 N+1 问题其实应该叫做 1+N 问题,这只是一个数据库设计模式的问题 .但是会对数据库带来很大的压力,一个简单的列表页
可能会有几百次数据库查询
N+1 问题并不是 ORM 独有,只是使用 orm 的时候,数据库表中的行变成一个对象,于是很自然的就容易使用上面的方法来进行查
询不使用 orm 进行编程的情况,一般直接用子查询或者 inner join
select a.*,c.name from article a,category b where a.category_id
= b.id
子查询或者 inner join 对数据库来说,也是很费资源的操作,因为需要锁表,高并发的情况下很容易锁死
要解决 1+N 问题一般有 3 种方法
1. 数据库反范式设计,说直白点,就是把表合并,设计成冗余表,这可能会带来两个问题
1.
2.
表中存在大量的重复数据项
表中出现大量的空项,整个表格变成一个稀疏矩阵(sparse matrix)
评论0
最新资源