feat(perf): ORM-623 add cache for migration data (#5471)
This PR improves the performance of the `prisma migrate dev` command by
avoiding redundant shadow database work.
During the execution of `prisma migrate dev` Prisma creates a
`DatabaseSchema` based of the list of existing migrations for up to 3
times. In most cases with the exact same input of migrations and hence
same output of `DatabaseSchema`. This is a costly operation as it needs
to apply the migrations to a shadow database. This becomes especially
slow when connecting to a remote database like Prisma Postgres.
Prisma now caches this result after the first computation. There are
still cases where the list of migrations provided as input can vary
between the invocations. Hence the cache uses a hash of the provided
migrations as cache key.
This implementation was a bit tricky as the `DatabaseSchema` struct and
parts of the `SqlDatabaseSchema` (the `ConnectorData`) are type erased
constructs. This made a simple `clone` impossible and I had to do some
workarounds. Cloning is required so one variant of the `DatabaseSchema`
can be stored in the cache while another clone can be passed on for
further processing in the diffing process.
In my testing against Prisma Postgres this change decreased the runtime
by ~50%. From ~2 minutes before my changes to now ~1 minute.
- [ORM-623: Improve migration command
performance](https://linear.app/prisma-company/issue/ORM-623/improve-migration-command-performance)
- [Original investigation work on
Notion.](https://www.notion.so/prismaio/ORM-600-Investigate-Prisma-migrations-being-slow-1919e8aecef780c5a762c1643f2a1c74)