После рефакторинга

This commit is contained in:
2025-11-18 14:44:32 +03:00
parent 55759ec705
commit c8bcd1adf0
56 changed files with 204454 additions and 683 deletions

View File

@@ -0,0 +1,90 @@
# Отчет об оптимизации запросов в ObjItemListView
## Задача 29: Оптимизировать запросы в ObjItemListView
### Выполненные изменения
#### 1. Добавлены select_related() для всех связанных моделей
Добавлены следующие связи через `select_related()`:
- `transponder`
- `transponder__sat_id`
- `transponder__polarization`
Эти связи уже были частично оптимизированы, но были добавлены недостающие.
#### 2. Добавлены prefetch_related() для mirrors и marks
Использованы оптимизированные `Prefetch` объекты:
```python
# Оптимизированный 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:
**Было:**
```python
mirrors_list = list(obj.geo_obj.mirrors.values_list('name', flat=True))
```
**Стало:**
```python
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! Количество запросов остается постоянным независимо от количества объектов.
### Структура запросов после оптимизации
1. **Основной запрос:** SELECT для ObjItem с JOIN для всех select_related связей
2. **Prefetch mirrors:** SELECT для Satellite через geo_mirrors (ManyToMany)
3. **Prefetch source:** SELECT для Source (если не покрыто select_related)
4. **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` - тест сравнения с baseline
- `test_objitem_scale.py` - тест масштабируемости
- `test_objitem_query_optimization.py` - базовый тест
- `test_objitem_detailed_queries.py` - детальный тест
## Заключение
Оптимизация успешно выполнена. Количество запросов к базе данных сокращено с ~51 до 4 запросов (улучшение на 92.2%), и это количество остается постоянным независимо от количества отображаемых объектов. Это значительно улучшит производительность страницы списка объектов, особенно при большом количестве записей.