Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » производительность lazy и обычных запросов. [RSS Feed]

#1 Май 17, 2012 09:43:50

Atterratio
От:
Зарегистрирован: 2011-09-17
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

производительность lazy и обычных запросов.

Кто ни будь знает, при большом объёме быза данных производительность lazy запросов отличается от производительности обычных? То есть будет ли разница и в чью пользу по скорости между:

a = Model.objects.filter(p1='s1').filter(p2='s2').filter(p3='s3')
b = Model.objects.all()
b = b.filter(p1='s1')
b = b.filter(p2='s2')
b = b.filter(p3='s3')



Отредактировано Atterratio (Май 17, 2012 09:44:59)

Офлайн

#2 Май 17, 2012 09:46:40

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

производительность lazy и обычных запросов.

По-моему между a и b никакой разницы. Запрос к базе ни в том ни в другом случае пока не выполнялся.
https://docs.djangoproject.com/en/1.4/ref/models/querysets/#when-querysets-are-evaluated



Отредактировано svas (Май 17, 2012 09:49:32)

Офлайн

#3 Май 19, 2012 18:48:01

Imposeren
От:
Зарегистрирован: 2009-04-06
Сообщения: 46
Репутация: +  1  -
Профиль   Отправить e-mail  

производительность lazy и обычных запросов.

lazy:

for item in Model.objecta.filter(p1='s1'):
    pass


not lazy (but all is in memory!)
for item in list(Model.objecta.filter(p1='s1')):
    pass

замечу что второй способ часто в разы быстрее, но и требовательнее к памяти



Офлайн

#4 Май 20, 2012 20:58:49

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

производительность lazy и обычных запросов.

Объясните в чем разница, кроме преобразования QuerySet в list?



Офлайн

#5 Май 20, 2012 21:12:44

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

производительность lazy и обычных запросов.

При преобразовании мы проходимся по QuerySet'у, а значит пользы от того, что это генератор, никакой. Это как range vs xrange.

Документация:

list().
Force evaluation of a QuerySet by calling list() on it. For example:
entry_list = list(Entry.objects.all())
Be warned, though, that this could have a large memory overhead, because Django will load each element of the list into memory. In contrast, iterating over a QuerySet will take advantage of your database to load data and instantiate objects only as you need them.



Отредактировано fata1ex (Май 20, 2012 21:14:09)

Офлайн

#6 Май 24, 2012 19:35:43

kmike
От:
Зарегистрирован: 2009-12-07
Сообщения: 56
Репутация: +  4  -
Профиль   Отправить e-mail  

производительность lazy и обычных запросов.

Вот это:

for item in Model.objects.filter(p1='s1'):
    pass
точно так же загрузит все данные в память. Запрос выполнится сразу, как начнется итерация; результат (весь) попадет из сервера БД в питоний драйвер БД (может что-то поменялось, но раньше большая часть драйверов БД не поддерживали постепенное получение результатов, или джанга их так использовала). А потом джанга будет создавать экземпляры модели постепенно (и запоминать/кешировать их). Отличие от варианта с list() в том, что при варианте с list() все экземпляры моделей создадутся сразу. Короче, непонятно, отчего способ с list() может быть в разы быстрее, или требовать больше памяти, тут по сути одно и то же происходит. Мне кажется, @Imposeren что-то путает тут.

Чтоб не кешировать экземпляры моделей, можно использовать вот такую конструкцию:
for item in Model.objects.filter(p1='s1').iterator():
    pass
вот это будет требовать меньше памяти, т.к. экземпляры моделей внутри кверисета кешироваться не будут. Это означает, например, что при повторной итерации будет выполнен еще один sql-запрос. Ну и с этим способом все равно можно потратить много памяти (хотя и меньше, чем без .iterator()), если драйвер БД (и его связка с джангой) не поддерживает итерацию, а вытаскивает с сервера все сразу.



Офлайн

  • Начало
  • » Django
  • » производительность lazy и обычных запросов.[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version