我遇到一些嚴重的性能問題與prefetch_related
Model 5 m2m領域,我預取也很少嵌套m2m領域。Django prefetch_related優化查詢,但仍然非常緩慢
class TaskModelManager(models.Manager):
def get_queryset(self):
return super(TaskModelManager, self).get_queryset().exclude(internalStatus=2).prefetch_related("parent", "takes", "takes__flags", "assignedUser", "assignedUser__flags", "asset", "asset__flags", "status", "approvalWorkflow", "viewers", "requires", "linkedTasks", "activities")
class Task(models.Model):
uuid = models.UUIDField(primary_key=True, default=genOptimUUID, editable=False)
internalStatus = models.IntegerField(default=0)
parent = models.ForeignKey("self", blank=True, null=True, related_name="childs")
name = models.CharField(max_length=45)
taskType = models.ForeignKey("TaskType", null=True)
priority = models.IntegerField()
startDate = models.DateTimeField()
endDate = models.DateTimeField()
status = models.ForeignKey("ProgressionStatus")
assignedUser = models.ForeignKey("Asset", related_name="tasksAssigned")
asset = models.ForeignKey("Asset", related_name="tasksSubject")
viewers = models.ManyToManyField("Asset", blank=True, related_name="followedTasks")
step = models.ForeignKey("Step", blank=True, null=True, related_name="tasks")
approvalWorkflow = models.ForeignKey("ApprovalWorkflow")
linkedTasks = models.ManyToManyField("self", symmetrical=False, blank=True, related_name="linkedTo")
requires = models.ManyToManyField("self", symmetrical=False, blank=True, related_name="depends")
objects = TaskModelManager()
查詢的數量是好的,數據庫查詢時間也沒關係,對於爲例,如果我詢問我的模型700點的對象,我有35查詢,平均查詢時間爲100〜200毫秒,但總的請求時間大約是8秒。
我碰到一些剖析,並指出,時間超過80%是花費在prefetch_related_objects
通話。
我使用Django==1.8.5
和djangorestframework==3.4.6
我歡迎任何方式來優化這個。 在此先感謝您的幫助。
編輯與select_related
:
我試圖通過麥金太爾
class TaskModelManager(models.Manager):
def get_queryset(self):
return super(TaskModelManager, self).get_queryset().exclude(internalStatus=2).select_related("parent", "status", "approvalWorkflow", "step").prefetch_related("takes", "takes__flags", "assignedUser", "assignedUser__flags", "asset", "asset__flags", "viewers", "requires", "linkedTasks", "activities")
新的結果仍是8秒與32個查詢和查詢的150ms的要求提出了改進時間。
編輯:
看來,門票已於Django的問題跟蹤3年前開業,是仍處於打開狀態:HTTPS://code.djangoproject.com/ticket/20577
好的,我試過了,結果不是很好。我有4個較少的查詢,但總體時間仍然是8秒。我認爲這個問題更多的是在'prefetch_related'而不是sql查詢的邏輯中。 –