所以我试图优化一个相当奇怪的查询,但这是一个遗留数据库,所以我用我所拥有的来凑合。这些是我正在尝试的查询。此时它们提供相同的输出。 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 并在having子句中使用它们来进一步过滤查询集),但我当然不喜欢如何这需要很长时间。是模板层慢还是实际查询层慢?我怎样才能最好地调试这个?
感谢您在糟糕的数据结构中寻求优化的帮助。
更新1:2011-10-03
所以我安装了 django-debugtoolbar 来进行一些窥探,并启用了 MySQL 常规日志记录并得出以下结果:
using .filter()
or .extra()
总查询计数为 2。使用.raw()
总查询计数为1984!!!(不忽略幽灵般的文学参考)
我的模板使用重新组合,然后循环执行该重新组合。没有遵循任何关系,没有使用除内置函数之外的模板标签。 Select_lated 没有被使用,我仍然只收到 2 个查询。查看mysql日志,果然——1984条查询。
当查看执行的查询时,基本上它看起来像每个{{ Modelinstance.field }}
django 正在做一个SELECT pk, field FROM Model WHERE Model.pk = Modelinstance.pk
如果你问我的话,这似乎完全错误。我在这里遗漏了一些东西还是 django 真的在查询中疯狂运行吗?
结束更新 1
UPDATE 2请参阅下面的答案
Greg