mysql - Django 双内连接与 mysql 慢

标签 mysql sql django join

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

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

应用中的模型:

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 的过滤器参数。 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。双内连接工作 < 1 秒

最佳答案

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

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

请参阅 B-Tree Index Characteristics 下的文档

关于mysql - Django 双内连接与 mysql 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15800286/

相关文章:

用于检索友谊的 MYSQL 查询只能以一种方式工作?

SQL双重比较

python - 在模板中渲染外键列表

mysql - 检查一段时间内的最大记录数

mysql - 选择指定年份的新商品或返回商品

python - 尽管设置了 STATIC_URL 和 STATIC_ROOT,DJango 仍找不到静态文件

javascript - Django 如何配置为管理员使用备用静态目录

python - "IndexError: list index out of range"在为 MySQL DB 充电时

mysql - 删除 SQL 语法错误

php - 从 PDO 查询的表单中检索信息的问题