Entity Framework: 数据量大迁移慢
Entity Framework: Slow migrations with large volumes of data
我们在数据层中使用 Entity Framework 核心,发现在 table 上对大量数据(数百万行)进行大量操作时,迁移速度非常慢).
例如,目前我们正在调整整个数据库中字符串 (varchar) 列的大小。随着每个列长度的变化,EF 将删除所有 table 索引和约束并重新创建它们。例如,如果我们有 1 个索引和 10 个更改的列,EF 将删除并重新创建索引 10 次,而不是简单地删除索引一次,更改列,然后再次重新创建索引。
在我们的某些 table 中,单个列更改需要 30 多分钟才能完成,而且我们有大约 200 个列更改的顺序。
是否可以更改此行为以在迁移开始时删除所有索引并在结束时重新创建它们?
如果您的列长度更改全部发生在一次迁移中,您应该能够执行类似 migrationBuilder.Sql(@"-- drop index statements here");
的操作,然后更改所有列长度,然后 migrationBuilder.Sql(@"-- recreate index statements here");
我认为这里的关键是确保您在这些语句之间进行尽可能多的列长度更改,以最大限度地减少对性能的影响。当然,要对您同时进行的所有更改进行风险评估。
我们最终创建了两个迁移来解决这个问题。
首先,我们将隐藏 DbContext
class 中的所有索引定义。然后我们创建一个迁移,它自然会删除所有索引。
其次,我们对数据结构进行更改并取消注释索引定义。第二次迁移会改变结构并重新添加索引。
我们在数据层中使用 Entity Framework 核心,发现在 table 上对大量数据(数百万行)进行大量操作时,迁移速度非常慢).
例如,目前我们正在调整整个数据库中字符串 (varchar) 列的大小。随着每个列长度的变化,EF 将删除所有 table 索引和约束并重新创建它们。例如,如果我们有 1 个索引和 10 个更改的列,EF 将删除并重新创建索引 10 次,而不是简单地删除索引一次,更改列,然后再次重新创建索引。
在我们的某些 table 中,单个列更改需要 30 多分钟才能完成,而且我们有大约 200 个列更改的顺序。
是否可以更改此行为以在迁移开始时删除所有索引并在结束时重新创建它们?
如果您的列长度更改全部发生在一次迁移中,您应该能够执行类似 migrationBuilder.Sql(@"-- drop index statements here");
的操作,然后更改所有列长度,然后 migrationBuilder.Sql(@"-- recreate index statements here");
我认为这里的关键是确保您在这些语句之间进行尽可能多的列长度更改,以最大限度地减少对性能的影响。当然,要对您同时进行的所有更改进行风险评估。
我们最终创建了两个迁移来解决这个问题。
首先,我们将隐藏 DbContext
class 中的所有索引定义。然后我们创建一个迁移,它自然会删除所有索引。
其次,我们对数据结构进行更改并取消注释索引定义。第二次迁移会改变结构并重新添加索引。