Окружающая среда:
Django=="2.2"
Python=="3.6.8"
debug_toolbar=="1.11"
rest_framework=="3.8.2"
Фон:
Переходя от конечных точек DRF на основе функций к представлениям / наборам на основе классов, я обнаружил, что представления на основе классов работают немного лучше без вложенных отношений и намного хуже с вложенными отношениями.
Контекст модели псевдокода:
Creator:
ForeignKey.Shipments[]
Unit:
ForeignKey.Shipments[]
Shipment:
ForeignKey.Addresses[]
ForeignKey.Creator
ForeignKey.Unit
Address:
Street
City
State
Интересный контекст сериализатора:
Unit:
Meta:
Depth = 1
Creator:
Meta:
Depth = Infinite
При сравнении Viewsets вышеуказанной структуры с эквивалентным @apiview
, я нахожу:
/addresses
работает немного лучше на счетчике запросов SQL (0,9x), с нагрузкой на процессор в 1,1x (ожидается)
/creators
работает немного хуже на SQL-запросе (1.1x), с 3.9x нагрузкой на процессор (ожидается)
/creators/1
с набором данных только для чтения работает немного лучше на счетчике запросов SQL (0,9x), с нагрузкой на процессор 3,4x (неожиданно)
/creators/1
с записываемым набором данных значительно хуже работает с SQL-запросом (3,3x), со значительными 5,9x нагрузками на ЦП (неожиданно)
/units/1
с записываемым представлением работает значительно хуже на SQL-запросе (4.4x), с огромными 7.9x нагрузками на процессор (ОЧЕНЬ неожиданно)
- Обе формы представлений не выигрывают от / игнорируют
prefetch_related
использования от get_queryset
полностью (ОЧЕНЬ неожиданно)
Разбивка извлечения против @apiview
:
(240 queries including 235 similar and 120 duplicates)
Разбивка извлечения против viewsets.ReadOnlyModelViewSet
:
(208 queries including 200 similar and 78 duplicates )
Разбивка извлечения против viewsets.ModelViewSet
:
(803 queries including 801 similar and 801 duplicates )
Все это кажется очень не интуитивным.
Как возможно, чтобы два типа конечных точек, использующих один и тот же сериализатор, работали так по-разному?
По сравнению с представлениями, основанными на функциях, кажется, что классовые представления и наборы набирают массивную производительность ЦП и SQL, где задействованы внешние ключи, и я не могу найти никакой реальной причины.
Я ожидаю, что N + 1 запросы будут работать плохо, но я не ожидаю, что они будут выполнять больше плохо в зависимости от того, какой стиль конечной точки DRF обслуживает их.
Есть ли объяснение, почему это происходит?