gpt4 book ai didi

Django:为什么 Foo.objects.extra(...) 比 Foo.objects.raw 快得多?

转载 作者:行者123 更新时间:2023-12-04 19:17:24 25 4
gpt4 key购买 nike

所以我试图优化一个相当奇怪的查询,但这是一个遗留数据库,所以我只能用我现有的。这些是我正在尝试的查询。在这一点上,它们提供相同的输出。 w 是我的查询集。

def future_schedule(request):

past = datetime.date.today()-datetime.timedelta(days=730)

extra_select = {
'addlcomplete': 'SELECT Complete FROM tblAdditionalDates WHERE Checkin.ShortSampleID = tblAdditionalDates.ShortSampleID',
'addldate': 'SELECT AddlDate FROM tblAdditionalDates WHERE Checkin.ShortSampleID = tblAdditionalDates.ShortSampleID'
}
extra_where = ['''(Checkin.Description <> "Sterilization Permit" AND Checkin.Description <> "Registration State" AND Checkin.Description <> "Miscellaneous" AND Checkin.Description <> "Equipment Purchase" AND Checkin.DateArrived > %s AND Checkin.DateCompleted IS NULL AND Checkin.Canceled = 0) OR (Checkin.Description <> "Sterilization Permit" AND Checkin.Description <> "Registration State" AND Checkin.Description <> "Miscellaneous" AND Checkin.Description <> "Equipment Purchase" AND Checkin.DateArrived > %s AND Checkin.DateCompleted IS NOT NULL AND Checkin.DateFinalCompleted IS NULL AND Checkin.DateFinalExpected IS NOT NULL AND Checkin.Canceled = 0) '''
]
extra_params = [past, past]

w = Checkin.objects.extra(select=extra_select, where=extra_where, params=extra_params)

# OR This one

w = Checkin.objects.raw('''SELECT Checkin.SampleID, Checkin.ShortSampleID, Checkin.Company, A.Complete, Checkin.HasDates, A.AddlDate FROM Checkin LEFT JOIN (SELECT ShortSampleID, Complete, AddlDate FROM tblAdditionalDates) A ON A.ShortSampleID = Checkin.ShortSampleID WHERE (Checkin.Description <> "Sterilization Permit" AND Checkin.Description <> "Registration State" AND Checkin.Description <> "Miscellaneous" AND Checkin.Description <> "Equipment Purchase" AND Checkin.DateArrived > "2009-01-01" AND Checkin.DateCompleted IS NULL AND Checkin.Canceled = 0) OR (Checkin.Description <> "Sterilization Permit" AND Checkin.Description <> "Registration State" AND Checkin.Description <> "Miscellaneous" AND Checkin.Description <> "Equipment Purchase" AND Checkin.DateArrived > "2009-01-01" AND Checkin.DateCompleted IS NOT NULL AND Checkin.DateFinalCompleted IS NULL AND Checkin.DateFinalExpected IS NOT NULL AND Checkin.Canceled = 0)''')

这两者都返回相同数量的记录 (322)。 .extra 呈现 HTML 的速度比 .raw 查询快 10 秒左右,对于所有密集型目的,.raw 查询甚至稍微不那么复杂。有没有人知道为什么会这样?根据我的结构,.raw 可能是我获取所需数据的唯一方法(我需要在 extra_select dict 中使用 addlcomplete 和 addldate 并在 Have 子句中使用它们来进一步过滤查询集)但我当然不喜欢如何它需要很长时间。是在模板层上速度较慢还是实际查询层?我怎样才能最好地调试这个?

感谢您在糟糕的数据结构中寻求优化的帮助。

更新 1:2011-10-03

所以我安装了 django-debugtoolbar 来窥探一下,我启用了 MySQL 常规日志记录并提出了以下内容:

使用 .filter().extra()查询总数为 2。使用 .raw()查询总数为 1984!!! (幽灵般的文学引用不被忽视)

我的模板正在使用重组,然后循环遍历重组。没有遵循任何关系,没有使用除内置之外的模板标签。 Select_related 没有被使用,我仍然只得到 2 个查询。查看mysql日志,果然——1984查询。

查看执行的查询时,基本上每个 {{ Modelinstance.field }} 都是这样的。 django 正在做一个 SELECT pk, field FROM Model WHERE Model.pk = Modelinstance.pk如果你问我,这似乎完全错误。我在这里遗漏了什么还是 django 真的在查询中狂奔?

结束更新 1

更新 2
请参阅下面的答案

格雷格

最佳答案

好的。这是我的最终结论。虽然 Furbeenator 关于内部 Django 优化是正确的,但事实证明存在更大的用户错误导致速度变慢和上述数千个查询。

Raw queryset docs 中清楚地记录了这一点。当您推迟字段(即不使用 SELECT * FROM ... )并且只选择特定的字段时( SELECT Checkin.Sampleid, ... 您未选择的字段仍然可以访问,但需要另一个数据库调用。因此,如果您选择一个子集原始查询中的字段,而您忘记了在模板中使用的查询中的字段,Django 执行数据库查找以找到您在模板中引用的字段,而不是提示它不存在或其他什么。所以,让我们说你从你的查询中遗漏了 5 个字段(这就是我所做的),你最终在你的模板中引用了 300 条记录,你正在循环。这会导致 1500 次额外的数据库点击来获取每条记录的这 5 个字段。

因此,请注意隐藏的引用并感谢上帝 Django Debug Toolbar

关于Django:为什么 Foo.objects.extra(...) 比 Foo.objects.raw 快得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7636859/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com