Итак, я пытаюсь оптимизировать довольно странный запрос, но это устаревшая база данных, поэтому я справляюсь с тем, что имею.Это запросы, которые я пытаюсь.Они обеспечивают одинаковый выход на данный момент.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 примерно на 10 секунд быстрее, чем запрос .raw, и для всех интенсивных целей запрос .raw даже менее сложен.Кто-нибудь знает, почему это может быть?Исходя из моей структуры, .raw может быть единственным способом получения нужных мне данных (мне нужны addlcomplete и addldate в dict extra_select и использовать их в предложении 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 действительно сходит с ума с запросами?
END UPDATE 1
UPDATE 2 См. Ответ ниже
Грег