Очень медленный запрос к базе данных при миграции с django 1.8 на django 3.2
Я перевел проект с django1.8 на django3.2. Я использую ту же базу данных, но функция, которую я использую для построения отчета, работает в четыре раза медленнее (8 секунд на Django1.8 и 30/40 секунд на django3.2). База данных - MySQL версии 5.7 (я также пробовал версию 8.0.32, но ничего не изменилось).
Это запрос:
qs = PartitaDanno.objects.filter(incarico__cliente_intestatario_fattura_id=8006
).select_related('incarico', 'anagrafica_assctp', 'incarico__naturaincarico'
).prefetch_related('rate'
).order_by('-incarico__anno', '-incarico__numero', 'pk')
PartitaDanno - это таблица с 16000 строк, а модель имеет 215 полей (я знаю... я не писал этого). Результат этого запроса составляет всего 1700 строк... очень маленький результат. Необычно то, что даже если я использую простой запрос к этой модели типа
qs = PartitaDanno.objects.filter(incarico__cliente_intestatario_fattura_id=8006)
На итерацию результата этого базового запроса уходит 20 секунд... Я не понимаю. Необработанный sql запрос одинаков в обеих версиях Django. Вот первый необработанный запрос queryset:
Вот результат работы queryset.explain():
-> Sort row IDs: sinistri_incarico.anno DESC, sinistri_incarico.numero DESC, sinistri_partitadanno.id (actual time=163.955..172.010 rows=1761 loops=1)
-> Table scan on <temporary> (cost=2518.91..2544.83 rows=1874) (actual time=153.040..163.135 rows=1761 loops=1)
-> Temporary table (cost=2518.90..2518.90 rows=1874) (actual time=153.007..153.007 rows=1761 loops=1)
-> Nested loop left join (cost=2331.46 rows=1874) (actual time=0.247..62.163 rows=1761 loops=1)
-> Nested loop inner join (cost=1675.43 rows=1874) (actual time=0.224..52.547 rows=1761 loops=1)
-> Nested loop left join (cost=1019.40 rows=1677) (actual time=0.089..17.068 rows=1677 loops=1)
-> Index lookup on sinistri_incarico using b842d1d4b6d5fa98d8dc06d2c92e02c5 (cliente_intestatario_fattura_id=8006) (cost=432.45 rows=1677) (actual time=0.081..15.586 rows=1677 loops=1)
-> Single-row index lookup on sinistri_naturaincarico using PRIMARY (id=sinistri_incarico.naturaincarico_id) (cost=0.25 rows=1) (actual time=0.001..0.001 rows=1 loops=1677)
-> Index lookup on sinistri_partitadanno using sinistri_pa_incarico_id_398e55f0a3d8c2c0_fk_sinistri_incarico_id (incarico_id=sinistri_incarico.id) (cost=0.28 rows=1) (actual time=0.018..0.021 rows=1 loops=1677)
-> Single-row index lookup on T5 using PRIMARY (id=sinistri_partitadanno.anagrafica_assctp_id) (cost=0.25 rows=1) (actual time=0.005..0.005 rows=1 loops=1761)
Конечно, он замедляется, когда я начинаю итерировать набор запросов с помощью цикла for. Я не использую iterator() в сложном запросе, потому что я использую prefetch_related.
Спасибо за помощь!
Я решил эту проблему! Проблема вызвана model_utils FieldTracker и Django3.2. Вот проблема: https://github.com/jazzband/django-model-utils/issues/323