#34841: Reverse migrations model state rendering slow with moderate to large
migrations
------------------------------------------------+------------------------
               Reporter:  David Sanders         |          Owner:  nobody
                   Type:  Cleanup/optimization  |         Status:  new
              Component:  Migrations            |        Version:  4.2
               Severity:  Normal                |       Keywords:
           Triage Stage:  Unreviewed            |      Has patch:  0
    Needs documentation:  0                     |    Needs tests:  0
Patch needs improvement:  0                     |  Easy pickings:  0
                  UI/UX:  0                     |
------------------------------------------------+------------------------
 Relevant discussion: https://forum.djangoproject.com/t/migrating-
 backwards-takes-orders-of-magnitude-longer-than-migrating-forwards/20873/2

 Investigations revealed 2 things.

 1. this block of code in `db/migrations/excecutor.py` was responsible for
 a large portion of processing time:
 
https://github.com/django/django/blob/b8b2f7451201f3ff60891b6ce55f177400700d7a/django/db/migrations/executor.py#L222-L232

 In my small project with only a moderate number of migrations, a simple
 reverse migrate of the last migration on the main app took ~20s. The block
 below was responsible for ~16s.

 {{{
         # Generate the post migration state by starting from the state
 before
         # the last migration is unapplied and mutating it to include all
 the
         # remaining applied migrations.
         last_unapplied_migration = plan[-1][0]
         state = states[last_unapplied_migration]
         for index, (migration, _) in enumerate(full_plan):
             if migration == last_unapplied_migration:
                 for migration, _ in full_plan[index:]:
                     if migration in applied_migrations:
                         migration.mutate_state(state, preserve=False)
                 break
 }}}

 2. these 2 lines appeared to be responsible for the slowdown, commenting
 them out made the block above run almost instantly:
 
https://github.com/django/django/blob/b8b2f7451201f3ff60891b6ce55f177400700d7a/django/db/migrations/executor.py#L203-L204

 {{{
                 if "apps" not in state.__dict__:
                     state.apps  # Render all -- performance critical
 }}}

 I have a small patch to move record the unapplied state before these 2
 lines and clone it, removing the `state.apps` attribute.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34841>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018a94dcdbae-91edbd0a-bdbe-4fb9-bb1e-d38a5a281415-000000%40eu-central-1.amazonses.com.

Reply via email to