После рефакторинга
This commit is contained in:
90
QUERY_OPTIMIZATION_REPORT.md
Normal file
90
QUERY_OPTIMIZATION_REPORT.md
Normal 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%), и это количество остается постоянным независимо от количества отображаемых объектов. Это значительно улучшит производительность страницы списка объектов, особенно при большом количестве записей.
|
||||
Reference in New Issue
Block a user