【问题标题】:Is using a (sequential) GUID the only viable alternative to a database generated ID?使用(顺序)GUID 是数据库生成 ID 的唯一可行替代方案吗?
【发布时间】:2013-01-22 08:07:09
【问题描述】:

我们正在使用 Entity Framework 5 Code First 方法将我们的 MS-Access 数据库迁移到 SQL Server Compact 4.0。我们发现使用数据库生成的整数 ID 非常慢,更糟糕的是,延迟随着数据库的大小呈指数增长。这使得无法使用 Identity 列,并且在与实体框架配对的 SQL Server Compact 4.0 中,此功能的实现似乎很糟糕。

因此,我们进行了一些测试,发现使用客户端生成的密钥将操作插入速度提高了至少 20 倍,插入的指数增长消失了。

现在我们正在寻找一种生成客户端 ID 的最佳方法。使用 GUID 似乎是最安全的选择,但我读到这会对读取操作产生负面影响。是否有使用客户端生成的自动递增整数的策略?

编辑: 我将进一步调查导致该问题的潜在问题。同时,我的真正问题可以回答吗? :-)

编辑2: 令人非常恼火的是,似乎没有人相信在 EF 和 SQL Server compact 4.0 中使用 auto-id 如此缓慢的断言。我在a separate question 上发布了关于这个问题的概念证明,应该很容易重现。

【问题讨论】:

  • 我怀疑您的应用程序逻辑或测试方法中存在其他问题。使用 IDENTITY 列生成整数 ID 不应该很慢,也不应该使使用标识列成为不可能。
  • 我再次同意@AaronBertrand,他们似乎不太可能得到这么基本的错误
  • @AaronBertrand 同样,似乎很难得到确认这个错误的测试:-)。另见:social.msdn.microsoft.com/Forums/en/adodotnetentityframework/…
  • 此问题已在 SQL Server Compact 4.0 版中得到修复
  • 为什么不能在 SQL Server 中关闭标识列,使用自动递增的整数 ID 复制数据,然后在 SQL 中打开标识列?您可以使用自动递增的整数告诉 SQL 从何处再次获取。

标签: database entity-framework ef-code-first sql-server-ce identity-column


【解决方案1】:

我看到的解决方案。

a)尝试修复性能问题。我的建议(不要在上下文中使用大量实体。)尽可能少地尝试业务问题。不要使用合并跟踪等...请参阅 EF 性能提示。 http://blogs.msdn.com/b/wriju/archive/2011/03/15/ado-net-entity-framework-performance-tips.aspxhttp://msdn.microsoft.com/en-au/library/cc853327.aspx

b) 使用指南。外部分配(不是顺序的,但速度很快)

c) 使用在内存中运行的客户整数生成器,可以一次分配多个键,并且可以保持当前状态。 SAP 使用此技术。他们称之为“数字范围”。 可以非常快,但不如 b)。

顺便说一句,我使用 GUID 而不是数据库生成的 ID 来制作部分数据库副本和迁移更容易/更容易。 :-)

【讨论】:

  • 在索引表中使用非顺序 guid 会导致每次写入一行时重新平衡索引树!
  • @Bernd 我强烈喜欢均匀分布的 Guid。尤其是在大容量场景中。大我的意思是> 1亿行。当您获得 > 10 亿行时,这一点非常重要。更多关于为什么对stackoverflow.com/questions/13149139/…感兴趣。顺便说一句,如果一个表是为增长而分区的,并且 50% 的表使用是插入,那么均匀分布的 Guids 会胜出。曾在一家银行与 DB2 专家一起完成此练习,该银行每月仅一个表就有超过 1 亿行。
【解决方案2】:

我不认为身份生成方式是性能问题的根源。
我认为如果您想在迁移过程中获得更好的性能, 在转换过程之前,您可以禁用主键和外键等约束 在你的主要桌子上。 (这可以通过脚本或手动完成)
但是,数据完整性将成为您的新关注点,并且您的转换代码必须强大,因此在转换过程之后,可以完成启用约束。
希望这会有所帮助。

【讨论】:

  • 感谢您的意见,但您对约束的假设是错误的。按照我的另一个问题的链接,证明使用 EF5 + SQLServer Compact 4.0 时使用存储生成的 ID 插入非常慢
【解决方案3】:

如果您使用 EF 移动大量数据,那么您做错了。使用 ADO.NET,例如使用 BULK COPY 方法(对于 SQL CE,使用 SqlCeUpdateableRecord)。您可以使用我的 SqlCeBulkCopy 库来节省一些编码工作。

【讨论】:

  • 实际上我现在使用您的 BulkCopy 方法。但它不会更新实体中生成的 ID。什么是“大量”? EF5 + SQL Server Compact 需要 30 秒在我们的数据库表中写入 250 条记录,其中包含一个 Identity 列,当我在客户端上生成 ID 时,这会下降到一秒以下。那不可能是好的。使用 bulkkcopy 所需的时间可以忽略不计。
  • 您是否尝试过使用 BulkCopy API 的 KeepIdentity 选项?
  • 失败:由于所有实体的 ID 为零,因此引发了重复的主键异常。
猜你喜欢
  • 2017-10-30
  • 1970-01-01
  • 2011-06-20
  • 2010-10-06
  • 2016-12-17
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多