Django ORM 数据库查询优化
Django ORM DB Query Optimization
我有一个包含两个数据库命中的查询。
其中第一个包含 'aggregate' - 所以它立即执行。
我想知道我是否可以将它减少到只有一个 DB hit。
查询是:
“找到比德克萨斯州所有客户 ID 都大的客户。”
两个查询集是:
highest_tx_id = Customer.objects.filter(state='TX').aggregate(Max('id'))
res = Customer.objects.filter(id__gt=highest_tx_id['id_max'])
添加示例:
>>> reset_queries()
>>> highest_tx_id = Customer.objects.filter(state='TX').aggregate(Max('id'))
>>> res = Customer.objects.filter(id__gt=highest_tx_id['id__max'])
>>> connection.queries
[{'sql': 'SELECT MAX("customer"."id") AS "id__max" FROM "customer" WHERE "customer"."state" = \'TX\'', 'time': '0.001'}]
>>> res
<QuerySet [<Customer: Customer object (550)>, <Customer: Customer object (551)>, <Customer: Customer object (552)>, <Customer: Customer object (553)>, <Customer: Customer object (555)>, <Customer: Customer object (661)>, <Customer: Customer object (665)>]>
>>> connection.queries
[{'sql': 'SELECT MAX("customer"."id") AS "id__max" FROM "customer" WHERE "customer"."state" = \'TX\'', 'time': '0.001'}, {'sql': 'SELECT "customer"."id", "customer"."fname", "customer"."lname", "customer"."address", "customer"."city", "customer"."state", "customer"."zip_code", "customer"."phone", "customer"."company_name" FROM "customer" WHERE "customer"."id" > 444 LIMIT 21', 'time': '0.001'}]
>>>
有什么方法可以使用 1 个数据库命中来执行这些类型的查询?
您可以尝试使用 Subquery。
from django.db.models import Subquery
highest_tx_id = Customer.objects.filter(state='TX').aggregate(Max('id'))['id__max']
res = Customer.objects.filter(id__gt=Subquery(highest_tx_id))
在@TaipanRex 的回答的基础上,您可以这样做:
from django.db.models import Subquery
highest_tx_id = Customer.objects.filter(state='TX').order_by('-id').values('id')[:1]
res = Customer.objects.filter(id__gt=Subquery(highest_tx_id))
我有一个包含两个数据库命中的查询。
其中第一个包含 'aggregate' - 所以它立即执行。
我想知道我是否可以将它减少到只有一个 DB hit。
查询是:
“找到比德克萨斯州所有客户 ID 都大的客户。”
两个查询集是:
highest_tx_id = Customer.objects.filter(state='TX').aggregate(Max('id'))
res = Customer.objects.filter(id__gt=highest_tx_id['id_max'])
添加示例:
>>> reset_queries()
>>> highest_tx_id = Customer.objects.filter(state='TX').aggregate(Max('id'))
>>> res = Customer.objects.filter(id__gt=highest_tx_id['id__max'])
>>> connection.queries
[{'sql': 'SELECT MAX("customer"."id") AS "id__max" FROM "customer" WHERE "customer"."state" = \'TX\'', 'time': '0.001'}]
>>> res
<QuerySet [<Customer: Customer object (550)>, <Customer: Customer object (551)>, <Customer: Customer object (552)>, <Customer: Customer object (553)>, <Customer: Customer object (555)>, <Customer: Customer object (661)>, <Customer: Customer object (665)>]>
>>> connection.queries
[{'sql': 'SELECT MAX("customer"."id") AS "id__max" FROM "customer" WHERE "customer"."state" = \'TX\'', 'time': '0.001'}, {'sql': 'SELECT "customer"."id", "customer"."fname", "customer"."lname", "customer"."address", "customer"."city", "customer"."state", "customer"."zip_code", "customer"."phone", "customer"."company_name" FROM "customer" WHERE "customer"."id" > 444 LIMIT 21', 'time': '0.001'}]
>>>
有什么方法可以使用 1 个数据库命中来执行这些类型的查询?
您可以尝试使用 Subquery。
from django.db.models import Subquery
highest_tx_id = Customer.objects.filter(state='TX').aggregate(Max('id'))['id__max']
res = Customer.objects.filter(id__gt=Subquery(highest_tx_id))
在@TaipanRex 的回答的基础上,您可以这样做:
from django.db.models import Subquery
highest_tx_id = Customer.objects.filter(state='TX').order_by('-id').values('id')[:1]
res = Customer.objects.filter(id__gt=Subquery(highest_tx_id))