【发布时间】:2026-01-09 17:35:02
【问题描述】:
所以我正在尝试优化一个相当奇怪的查询,但这是一个遗留数据库,所以我只用我所拥有的。这些是我正在尝试的查询。此时它们提供相同的输出。 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 字典中的 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 请看下面的答案
格雷格
【问题讨论】:
标签: django django-models django-templates query-optimization django-queryset