#python #django
#python #django
Вопрос:
У меня есть набор запросов примерно из 1500 записей из запроса Django ORM. Я использовал методы select_related() и only(), чтобы убедиться, что запрос является сжатым. Я также использовал connection.запросы, чтобы убедиться, что существует только этот один запрос. То есть я убедился, что на каждой итерации не вызывается никаких дополнительных запросов.
Когда я запускаю запрос, вырезайте и вставляйте из соединения.запросы выполняются за 0,02 секунды. Однако для итерации по этим записям требуется семь секунд и ничего с ними не делать (pass).
Что я могу сделать, чтобы ускорить это? Что вызывает эту медлительность?
Комментарии:
1. Вам следует включить более подробную информацию о ваших моделях и запросе!
2. Вам также следует написать Django <— вот так 🙂 он был гитаристом, а не ди-джеем
Ответ №1:
Набор запросов может стать довольно тяжелым, когда он полон объектов модели. В похожих ситуациях я использовал метод .values в наборе запросов, чтобы указать нужные мне свойства в виде списка словарей, перебор которых может быть намного быстрее.
Документация Django: values_list
Комментарии:
1. Вы были правы. Оказывается, создание экземпляров объектов модели на каждой итерации вызывало много накладных расходов. Использование метода values сократило итерацию набора с семи секунд до всего лишь нескольких миллисекунд.
2. Потрясающе. Рад, что смог помочь.
3. Я заметил огромное увеличение производительности благодаря этому! Я выполнял итерацию набора запросов из 110000 элементов, на выполнение которого ушло почти 70 секунд. Повторение того же values_list заняло 5 секунд!
Ответ №2:
1500 записей — это далеко не большой набор данных, и семь секунд — это действительно слишком много. Вероятно, в ваших моделях есть какая-то проблема, вы можете легко проверить это, получив (как говорит Брэндон) запрос values(), а затем явно создать объект 1500, повторив словарь. Просто преобразуйте ValuesQuerySet в список перед построением, чтобы учесть подключение к БД.
Ответ №3:
Как вы выполняете итерацию по каждому элементу:
items = SomeModel.objects.all()
Регулярный цикл for для каждого
for item in items:
print item
Или с помощью итератора набора запросов
for item in items.iterator():
print item
Согласно документу, iterator()
может повысить производительность. То же самое применяется при циклировании очень большого списка Python или словарей, лучше всего использовать iteritems()
.
Комментарии:
1. Не уверен, сработает ли это, поскольку в основном итерация выполняется в шаблоне, и не уверен, есть ли у нас там .iterator() .
2. Я проверил это, и это действительно работает. Значительно ускорьте цикл for. С 0:00: 45.550635 до 0:00: 09.761178, то есть как минимум в 4 раза быстрее!!!
Ответ №4:
В Meta
объявлении вашей модели указано «упорядочивать по» полю, которое хранится в какой-либо другой связанной таблице? Если это так, ваша попытка выполнить итерацию может вызвать 1500 запросов, поскольку Django запускается и захватывает это поле для каждого элемента, а затем сортирует их. Показ вашего кода поможет нам решить проблему!