簡體   English   中英

如何刪除Django冗余內部聯接

[英]How to remove Django redundant inner join

我正在使用Django,我需要使用多個模型來過濾數據的查詢集。 這些模型具有相同的外鍵字段。

例:

class Snp(models.Model):
        chromosome = models.IntegerField()
        position = models.IntegerField()

    class Variant(models.Model):
        snp = models.ForeignKey(Snp, on_delete=models.CASCADE)
        genotype = models.IntegerField()

    class Mutation(models.Model):
        snp = models.ForeignKey(Snp, on_delete=models.CASCADE)
        synonymous = models.IntegerField()

    class Annot(models.Model):
        snp = models.ForeignKey(Snp, on_delete=models.CASCADE)
        gene = models.IntegerField()
q = Variant.objects.prefetch_related('snp').filter(snp__mutation__synonymous
    =1,snp__annot__gene=2)
    print(q.query)

這可能會創建以下SQL:

SELECT "md_variant"."id", "md_variant"."snp_id", "md_variant"."genotype" FROM "md_variant"
    INNER JOIN "md_snp" ON ("md_variant"."snp_id" = "md_snp"."id")
    INNER JOIN "md_annot" ON ("md_snp"."id" = "md_annot"."snp_id")
    INNER JOIN "md_mutation" ON ("md_snp"."id" = "md_mutation"."snp_id")
    WHERE ("md_annot"."gene" = 2 AND "md_mutation"."synonymous" = 1)

我使用了比上面更快的簡化SQL,並得到了相同的結果:

SELECT "md_variant"."id", "md_variant"."snp_id", "md_variant"."genotype" FROM "md_variant"
    INNER JOIN "md_annot" ON ("md_variant"."snp_id" = "md_annot"."snp_id")
    INNER JOIN "md_mutation" ON ("md_variant"."snp_id" = "md_mutation"."snp_id") 
    WHERE ("md_annot"."gene" = 2 AND "md_mutation"."synonymous" = 1)

我認為內部連接md_snp是不必要的,因為同一模型Snp的Mutation,Variant和Annot模型外鍵。 如何刪除此多余的內部聯接?

首先, prefetch_related()在這里沒有意義。

q = Variant.objects.filter(snp__mutation__synonymous=1, snp__annot__gene=2)
print(q.query)

您無法避免通過Snp Join ,因為您擁有SNP的 ForeignKey 如果您認為您的sql查詢更好,請執行原始sql查詢。 這不是問題。

在Django中執行原始SQL查詢

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM