Django ORM查询优化:如何将含聚合操作的两次DB hit查询优化为一次
可行实现方案
你可以利用Django ORM的子查询能力,将最大ID的聚合逻辑嵌入到主查询的条件中,全程只会触发一次DB hit。
实现代码
首先导入依赖:
from django.db.models import Max, Subquery
查询逻辑如下:
# 仅构造子查询逻辑,不会立即触发数据库查询 tx_max_id_subq = Customer.objects.filter(state='TX').annotate( max_tx_id=Max('id') ).values('max_tx_id')[:1] # 主查询将子查询作为过滤条件,直到访问结果时才会执行一次性SQL查询 res = Customer.objects.filter(id__gt=Subquery(tx_max_id_subq))
原理说明
你原来的写法触发两次查询的核心原因是aggregate()是立即执行方法,调用时就会马上发起DB请求拿到聚合结果。而上面的写法中:
- 子查询仅生成SQL逻辑片段,不会被主动执行
- 最终主查询生成的SQL会自动将聚合逻辑作为嵌套子查询,最终发给数据库的SQL为单条:
SELECT "customer".* FROM "customer" WHERE "customer"."id" > ( SELECT MAX("customer"."id") AS "max_tx_id" FROM "customer" WHERE "customer"."state" = 'TX' )
全程仅和数据库交互一次,和原有两次查询的返回结果完全一致。
内容的提问来源于stack exchange,提问作者LiorA
相关产品推荐
相关产品推荐

