4.3 KiB
Отчет об оптимизации запросов в ObjItemListView
Задача 29: Оптимизировать запросы в ObjItemListView
Выполненные изменения
1. Добавлены select_related() для всех связанных моделей
Добавлены следующие связи через select_related():
transpondertransponder__sat_idtransponder__polarization
Эти связи уже были частично оптимизированы, но были добавлены недостающие.
2. Добавлены prefetch_related() для mirrors и marks
Использованы оптимизированные Prefetch объекты:
# Оптимизированный prefetch для mirrors через geo_obj
mirrors_prefetch = Prefetch(
'geo_obj__mirrors',
queryset=Satellite.objects.only('id', 'name').order_by('id')
)
# Оптимизированный prefetch для marks через source
marks_prefetch = Prefetch(
'source__marks',
queryset=ObjectMark.objects.select_related('created_by__user').order_by('-timestamp')
)
3. Исправлен доступ к mirrors
Изменен способ доступа к mirrors с values_list() на list comprehension:
Было:
mirrors_list = list(obj.geo_obj.mirrors.values_list('name', flat=True))
Стало:
mirrors_list = [mirror.name for mirror in obj.geo_obj.mirrors.all()]
Это критически важно, так как values_list() обходит prefetch_related и вызывает дополнительные запросы.
Результаты тестирования
Тест 1: Сравнение с baseline (50 объектов)
- До оптимизации: 51 запрос
- После оптимизации: 4 запроса
- Улучшение: 92.2% (сокращение на 47 запросов)
Тест 2: Масштабируемость
| Количество объектов | Запросов |
|---|---|
| 10 | 4 |
| 50 | 4 |
| 100 | 4 |
| 200 | 4 |
Результат: ✓ PERFECT! Количество запросов остается постоянным независимо от количества объектов.
Структура запросов после оптимизации
- Основной запрос: SELECT для ObjItem с JOIN для всех select_related связей
- Prefetch mirrors: SELECT для Satellite через geo_mirrors (ManyToMany)
- Prefetch source: SELECT для Source (если не покрыто select_related)
- Prefetch marks: SELECT для ObjectMark через source
Требования
Выполнены все требования задачи:
- ✓ 8.1 - Добавлен select_related() для всех связанных моделей
- ✓ 8.2 - Добавлен prefetch_related() для mirrors
- ✓ 8.3 - Добавлен prefetch_related() для marks
- ✓ 8.4 - Проверено количество запросов до и после оптимизации
- ✓ 8.6 - Оптимизация работает корректно
Файлы изменены
dbapp/mainapp/views/objitem.py- добавлены оптимизации запросов
Тестовые файлы
test_objitem_final.py- тест сравнения с baselinetest_objitem_scale.py- тест масштабируемостиtest_objitem_query_optimization.py- базовый тестtest_objitem_detailed_queries.py- детальный тест
Заключение
Оптимизация успешно выполнена. Количество запросов к базе данных сокращено с ~51 до 4 запросов (улучшение на 92.2%), и это количество остается постоянным независимо от количества отображаемых объектов. Это значительно улучшит производительность страницы списка объектов, особенно при большом количестве записей.