使用 related_name 的查询在 Django 中的性能更高吗?
Are queries using related_name more performant in Django?
假设我设置了以下模型:
class Shop(models.Model):
...
class Product(models.Model):
shop = models.ForeignKey(Shop, related_name='products')
现在假设我们要查询 label
'demo' 商店中价格低于 100 美元的所有产品。有两种方法可以做到这一点:
shop = Shop.objects.get(label='demo')
products = shop.products.filter(price__lte=100)
或
shop = Shop.objects.get(label='demo')
products = Products.objects.filter(shop=shop, price__lte=100)
这两个查询有区别吗?第一个是使用 related_name
属性。我知道外键是有索引的,所以使用它们进行搜索应该会更快,但这适用于我们的第一种情况吗?
简答:这将导致等效个查询。
我们可以通过打印查询来进行测试:
>>> print(shop.products.filter(price__lte=100).query)
SELECT "app_product"."id", "app_product"."shop_id", "app_product"."price" FROM "app_product" WHERE ("app_product"."shop_id" = 1 AND "app_product"."price" <= 100)
>>> print(Product.objects.filter(shop=shop, price__lte=100).query)
SELECT "app_product"."id", "app_product"."shop_id", "app_product"."price" FROM "app_product" WHERE ("app_product"."price" <= 100 AND "app_product"."shop_id" = 1)
除了WHERE
中的条件互换外,两者是相等的。但通常这在数据库端没有任何区别。
如果您 不 对 Shop
对象本身感兴趣,您可以过滤:
products = Product.objects.filter(<b>shop__label='demo'</b>, price__lte=100)
这将在数据库级别进行 JOIN,从而一次性检索数据:
SELECT "app_product"."id", "app_product"."shop_id", "app_product"."price"
FROM "app_product"
INNER JOIN "app_shop" ON "app_product"."shop_id" = "app_shop"."id"
WHERE "app_product"."price" <= 100 AND "app_shop"."label" = demo
假设我设置了以下模型:
class Shop(models.Model):
...
class Product(models.Model):
shop = models.ForeignKey(Shop, related_name='products')
现在假设我们要查询 label
'demo' 商店中价格低于 100 美元的所有产品。有两种方法可以做到这一点:
shop = Shop.objects.get(label='demo')
products = shop.products.filter(price__lte=100)
或
shop = Shop.objects.get(label='demo')
products = Products.objects.filter(shop=shop, price__lte=100)
这两个查询有区别吗?第一个是使用 related_name
属性。我知道外键是有索引的,所以使用它们进行搜索应该会更快,但这适用于我们的第一种情况吗?
简答:这将导致等效个查询。
我们可以通过打印查询来进行测试:
>>> print(shop.products.filter(price__lte=100).query)
SELECT "app_product"."id", "app_product"."shop_id", "app_product"."price" FROM "app_product" WHERE ("app_product"."shop_id" = 1 AND "app_product"."price" <= 100)
>>> print(Product.objects.filter(shop=shop, price__lte=100).query)
SELECT "app_product"."id", "app_product"."shop_id", "app_product"."price" FROM "app_product" WHERE ("app_product"."price" <= 100 AND "app_product"."shop_id" = 1)
除了WHERE
中的条件互换外,两者是相等的。但通常这在数据库端没有任何区别。
如果您 不 对 Shop
对象本身感兴趣,您可以过滤:
products = Product.objects.filter(<b>shop__label='demo'</b>, price__lte=100)
这将在数据库级别进行 JOIN,从而一次性检索数据:
SELECT "app_product"."id", "app_product"."shop_id", "app_product"."price"
FROM "app_product"
INNER JOIN "app_shop" ON "app_product"."shop_id" = "app_shop"."id"
WHERE "app_product"."price" <= 100 AND "app_shop"."label" = demo