Джанго ударил MySQL даже после select_related ()? - PullRequest
1 голос
/ 28 августа 2009

Я пытаюсь оптимизировать вызовы базы данных, поступающие из довольно небольшого приложения Django. На данный момент у меня есть пара моделей, Inquiry и InquiryStatus. При выборе всех записей из MySQL, я получаю хороший оператор JOIN для двух таблиц, за которым следуют многочисленные запросы к таблице InquiryStatus. Почему Django все еще делает индивидуальные запросы, если я уже сделал select_related()?

Модели выглядят так:

class InquiryStatus(models.Model):
    status = models.CharField(max_length=25) 
    status_short = models.CharField(max_length=5)
    class Meta:
        ordering = ["-default_status", "status", "status_short"]

class Inquiry(models.Model):
    ts = models.DateTimeField(auto_now_add=True)
    type = models.CharField(max_length=50) 
    status = models.ForeignKey(InquiryStatus)
    class Meta:
        ordering = ["-ts"]

Представление, которое я создал для отладки, выглядит так:

def inquiries_list(request, template_name="inquiries/list_inquiries.js"):
    ## Notice the "print" on the following line.  Forces evaluation.
    print models.Inquiry.objects.select_related('status').all()
    return HttpResponse("CRAPSTICKS")

Я пытался использовать select_related(depth=1), без изменений. Каждый из посторонних запросов к базе данных выбирает один конкретный id в предложении WHERE.

Обновление:

Итак, есть один очень важный код, который следовало бы добавить в модели:

from fullhistory import register_model
register_model(Inquiry)
register_model(InquiryStatus)

В результате fullhistory (по причинам, которые я не могу понять) извлекал каждый отдельный результат и анализировал его.

Ответы [ 3 ]

0 голосов
/ 28 августа 2009

Код, который вы показали, вообще не должен генерировать никаких запросов - QuerySets оцениваются только при необходимости, а не когда они определены, и вы нигде не используете значение, поэтому выполнение не будет выполнено .

Пожалуйста, покажите нам шаблон или какой-то другой код, который на самом деле оценивает qs - разрезает его, повторяет, печатает или что-то еще.

0 голосов
/ 28 августа 2009

Кажется, что fullhistory завершает сериализацию объекта, который оценивает каждое поле в экземпляре, чтобы дать ему базу для сравнения.

Посмотрите на функцию get_all_data:

http://code.google.com/p/fullhistory/source/browse/trunk/fullhistory/fullhistory.py

Если кто-то захочет написать подробную причину, по которой это происходит, я с удовольствием отмечу этот ответ правильным.

0 голосов
/ 28 августа 2009

Я считаю, что это связано с ленивой оценкой. Django работает с БД только тогда и только тогда, когда это необходимо, а не при вызове моделей. Inquiry.objects.select_related ('status'). All ()

http://docs.djangoproject.com/en/dev/topics/db/queries/#id3

...