データベース内の外部キーselect_related()とprefetch_related使用()よく、それにより性能を向上させる、データベース要求の数を減らすことができます。
一例では、両方の用法、記載:
from django.db import models
class Province(models.Model):
name = models.CharField(max_length=10)
def __unicode__(self):
return self.name
class City(models.Model):
name = models.CharField(max_length=5)
province = models.ForeignKey(Province)
def __unicode__(self):
return self.name
class Person(models.Model):
firstname = models.CharField(max_length=10)
lastname = models.CharField(max_length=10)
visitation = models.ManyToManyField(City, related_name = "visitor")
hometown = models.ForeignKey(City, related_name = "birth")
living = models.ForeignKey(City, related_name = "citizen")
def __unicode__(self):
return self.firstname + self.lastname
select_related:
1フィールド(OneToOneField)および外部キーフィールド(ForeignKeyの)、select_relatedクエリセットを最適化するために使用されてもよいです。Select_relatedクエリセット()関数を使用した後、Djangoはもはやデータベースクエリの後に、必要なときにそのことを、オブジェクトに対応する対応する外部キーを取得しないこと。
私たちはすべての都市と地方とそれぞれのデータベースを印刷する必要がある場合は、最も直接的なアプローチは次のとおりです。
>>> citys = City.objects.all()
>>> for c in citys:
... print c.province
オブジェクトの数がn個あまり、各オブジェクトが外部キーフィールドkを持って、それがn *のk + 1回のSQLクエリにつながる場合、これは、線形SQLクエリになります。この場合、3つのオブジェクトがあるので、市内に4回、SQLクエリをリードしてきました:
SELECT `QSOptimize_city`.`id`, `QSOptimize_city`.`name`, `QSOptimize_city`.`province_id`
FROM `QSOptimize_city`
SELECT `QSOptimize_province`.`id`, `QSOptimize_province`.`name`
FROM `QSOptimize_province`
WHERE `QSOptimize_province`.`id` = 1 ;
SELECT `QSOptimize_province`.`id`, `QSOptimize_province`.`name`
FROM `QSOptimize_province`
WHERE `QSOptimize_province`.`id` = 2 ;
SELECT `QSOptimize_province`.`id`, `QSOptimize_province`.`name`
FROM `QSOptimize_province`
我々は、select_related()関数を使用する場合:
>>> citys = City.objects.select_related().all()
>>> for c in citys:
... print c.province
唯一の1つのSQLクエリは、明らかに大幅にSQLクエリの数を減らします:
SELECT `QSOptimize_city`.`id`, `QSOptimize_city`.`name`,
`QSOptimize_city`.`province_id`, `QSOptimize_province`.`id`, `QSOptimize_province`.`name`
FROM`QSOptimize_city`
INNER JOIN `QSOptimize_province` ON (`QSOptimize_city`.`province_id` = `QSOptimize_province`.`id`) ;
()prefetch_related
最適化するために多くの分野(のManyToManyField)と多くの分野の多くのために、(prefetch_related使用することができます)。おそらく、あなたは言うだろう、誰もOneToManyFieldの事ああと呼ばれていません。実際には、ForeignKeyのは、多対フィールドですが、フィールドがForeignKeyのは、フィールドの多くに関連していますさ。
prefetch_related()とselect_related()、非常に類似した設計されたSQLクエリの数ではなく、達成するのと同じ方法を減らすことです。(前者はinで文です)、後者でJOINステートメント SQLクエリで問題を解決するために、。結果のテーブルは非常に長くなり、JOIN、それは増加メモリフットプリントにつながるとSQL文の実行している時間が長くなりますので、しかし、多くの関係のために、ビット賢明上のアドレスにSQL文を使用します。n個のオブジェクト場合、フィールド多くミ物品に対応する各オブジェクトは、[シグマ結果テーブル(n)はミ行が生成されます。
prefetch_related()この問題を回避するには、個別のテーブルを照会し、その後のPythonとの関係に対処することです。私たちは、それができる、湖北省のすべての都市を取得したいです
>>> hb = Province.objects.prefetch_related('city_set').get(name__iexact=u"湖北省")
>>> for city in hb.city_set.all():
... city.name
トリガSQLクエリ:
SELECT `QSOptimize_province`.`id`, `QSOptimize_province`.`name`
FROM `QSOptimize_province`
WHERE `QSOptimize_province`.`name` LIKE '湖北省' ;
SELECT `QSOptimize_city`.`id`, `QSOptimize_city`.`name`, `QSOptimize_city`.`province_id`
FROM `QSOptimize_city`
WHERE `QSOptimize_city`.`province_id` IN (1);
私たちは、プリフェッチ達成するためのINステートメントを使用して、見ることができます。
概要:
以来select_related()は常に問題となっている単一のSQLクエリで解決、(しかしprefetch_related)関連する各テーブルのSQLクエリますのでselect_related、()効率が後者よりも通常は高いです。