Django双内连接用mysql慢

时间:2013-04-03 23:57:16

标签: mysql sql django join

为什么Django使用MySQL时这个查询速度慢? 我有三个我正在过滤的模型,它们与OneToOne和ForeignKey相互关联。我的数据库上有大约60k行的以下查询大约需要300秒才能完成。

resutls = A.objects.filter(b__c__candy__icontains="gummybears")
results  # <-- 300 seconds

app中的模型:

class A(models.Model):
    b = models.OneToOneField(B, default=None)
    a_charfield = models.CharField(max_length=40, default='')

class B(models.Model):
    b_charfield = models.CharField(max_length=40, default='')
    primary_id = models.CharField(max_length=40, unique=True, primary_key=True, default='', null=False)

class C(models.Model):
    b = models.ForeignKey('B')
    candy = models.CharField(db_index=True, max_length=40, default='')

打印result.query将MySQL查询显示为(我将列名组合为*):

SELECT *
FROM `app_a` 
INNER JOIN `app_b` ON (`app_a`.`b_id` = `app_b`.`primary_id`) 
INNER JOIN `app_c` ON (`app_b`.`primary_id` = `app_c`.`b_id`) 
WHERE `app_c`.`candy` LIKE %gummybears%  
ORDER BY `app_a`.`id` DESC

我有两个有效的解决方案。

  1. 将B的结果作为values_list获取,并用作A的过滤器arg。 https://docs.djangoproject.com/en/dev/ref/models/querysets/#in性能注意事项

    resutls = A.objects.filter(b__in=list(B.objects.filter(c__c_charfield__icontains="candy").values_list('pk', flat=True))
    
  2. 切换到postgresql。双内连接工作&lt; 1秒

1 个答案:

答案 0 :(得分:0)

以下代码中的前导%强制查询执行全表扫描而不是使用索引。如果糖果表不适合内存需要一段时间。

WHERE `app_c`.`candy` LIKE %gummybears%  

请参阅B-Tree Index Characteristics

下的文档