2010-10-08 1 views
1

Мне нужно получить 5 объектов, которые соответствуют определенным сложным критериям, и я не могу/не хочу передавать эти критерии в предложение WHERE (фильтр в django), поэтому мне нужно перебирать результаты, тестируя каждый запишите критерии, пока я не получу свои 5 объектов, после чего я хочу бросить запрос и никогда больше его не увидеть.Как правильно перебирать огромный QuerySet в django?

В большинстве случаев нужные мне записи будут в начале набора запросов, в худшем случае - в конце. Таблица огромна, и мне нужно всего 5 записей. Поэтому мой вопрос: как мне перебирать набор запросов, не используя django для кэширования результатов? Это должно быть сделано так, чтобы ни движок sql/django не записывал и не кэшировал результаты в любом месте.

ответ

1

Почему вы беспокоитесь о кешировании? Пусть Django или mysql делают то, что делают.

Если вы на него согнуты. Вы можете отключить кеширование для Django. Это довольно просто сделать в settings.py для вашего проекта.

Для Mysql, вам необходимо запустить некоторые querie (ы), чтобы отключить кэш запросов -

Попробуйте использовать SQL_NO_CACHE параметр в запросе. Вроде так

SELECT SQL_NO_CACHE * FROM TABLE 

Это остановит MySQL кэширование результатов, однако имейте в виду, что другие кеши ОС и дисков также могут влиять на производительность. Их сложнее обойти.

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

ИЛИ

Вы также могли бы сделать RESET QUERY CACHE

ИЛИ

FLUSH QUERY CACHE 

Хотя один момент, чтобы отметить, что я хотел бы предложить, позволяя Mysql обрабатывать положение WHERE как это имеет слой оптимизации запроса, который был бы очень эффективным, если бы у вас были проиндексированы нужные поля. Получив все результаты &, вы делаете то, что предложение WHERE может замедлить вас в зависимости от размера набора запросов. Просто кое что для раздумий. Думаю, правильный бенчмаркинг должен показать вам путь.

+0

вы знаете, как отключить кеш в postgresql? (Заставить его использовать курсор) –

+0

Вы можете избавиться от кэшей PostgreSQL в shared_buffers, перезапустив сервер PostgreSQL. Я не знаю, есть ли более удобный способ. Альтернативно, просто установите действительно минимальные общие_буферы, которых достаточно для ваших подключений, поэтому не хватает места для кэшированных данных. –

+0

@Thiado добавил больше материала, когда я отвечу. Надеюсь это поможет. Любая причина, по которой вы не склонны к кешированию? Некоторое тестирование производительности продолжается? –

0

В Django отсутствует глобальный кеш (см. Билет # 14). Это означает, что до тех пор, пока вы ничего не держите в руках, данные исчезнут и больше не будут кэшироваться. В этот момент сборщик мусора удалит выделение памяти при следующей очистке. Таким образом, код, такие как:

my_objects = [obj for obj in MyModel.objects.all() if my_complex_condition(obj)] 

Единственное кэширование Джанго бы сделать здесь в конкретном случае выше, и после этой строки любой ссылка на кэш не будет. Обратите внимание, что если Django не имеет кеша, память все равно будет заполняться таким же образом, и GC будет собирать строки индивидуально любым способом.

+0

Это не соответствует действительности.Если вы на самом деле запустите этот код, вы увидите, как снижается площадь памяти и поднимается и поднимается и поднимается – priestc