首页 > 解决方案 > Django模型集查找非常慢

问题描述

我在 Django 模型中的查找速度非常慢。

我有两张桌子:

class Scan(models.Model):
    scan_name = models.CharField(max_length=32, unique=True, validators=[alphanumeric_plus_validator])

class ScanProcessingInfo(models.Model):
    scan_name = models.CharField(max_length=32)
    processing_name = models.CharField(max_length=64)
    in_progress = models.BooleanField(default=False)

当我执行以下操作以获取具有特定处理名称的 ScanProcessingInfo 的所有 Scan 对象的列表时:

scans = models.Scan.objects.all()

        scan_set = []

        for scan in scans:
            if self.set_type_definition.test_scan(scan, self.arg1, self.arg2):
                scan_set.append(scan)


(test_scan routes to)

def get_proc_info_been_done(scan, spd_name):
    try:
        proc_info = models.ScanProcessingInfo.objects.get(scan_name = scan.scan_name)
    except models.ScanProcessingInfo.DoesNotExist:
        proc_info = None

    if proc_info == None:
        return False

    return not proc_info.in_progress

请求大约需要 10 秒。总共有 300 个 Scans 和 10 个 ScanProcessingInfos。数据库后端是一个 RDS MySQL 数据库。我也希望有人会告诉我使用字符串作为跨表标识符,但我怀疑这就是原因。

我确定我在做一些明显错误的事情,但希望得到指点,谢谢。

标签: pythonmysqldjango

解决方案


我认为您要问的是如何获取存在匹配 ScanProcessingInfo 的所有扫描。

首先要做的是声明实际的关系。你不需要改变你的数据库(你应该,但你不必);您可以使用现有的基础字段,但只需告诉 Django 将其视为外键。

class ScanProcessingInfo(models.Model):
    scan = models.ForeignKey('Scan', to_field='scan_name', db_field='scan_name', on_delete=models.DO_NOTHING)

现在您可以使用这种关系一次性获得所有扫描:

scan_set = Scan.objects.exclude(scanprocessinginfo=None)

编辑

要获取具有特定属性的所有匹配对象,请使用双下划线语法:

scan_set = Scan.objects.filter(scanprocessinginfo__processing_name=spd_name)

推荐阅读