Как мне ускорить итерацию больших наборов данных в Django

#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 запускается и захватывает это поле для каждого элемента, а затем сортирует их. Показ вашего кода поможет нам решить проблему!