【问题标题】:Index gets out of sync on bulk insert批量插入时索引不同步
【发布时间】:2016-03-31 16:03:02
【问题描述】:

我的 SQL Server 数据库有一个奇怪的问题。 我正在使用 SqlBulkCopy.WriteToServer 写入批量数据(大约 90,000 行),并且我还在使用 EF 的 AddRange 以 1,000 的批次写入大约 30,000 行。

这会导致这些表上的索引不同步,并且查询花费的时间比通常要长很多(10 分钟后超时,而不是几秒钟后的结果)。

在我手动重建索引后,查询再次快速,直到发生另一个这些导入。

我对批量加载的理解是它还应该更新索引。 我的问题是:这种行为是否有众所周知的原因?如果没有,我该如何解决这个问题?

【问题讨论】:

  • 我的两个想法是关于表/索引的统计信息,也许还有碎片,但可能没有那么多碎片。
  • @dfundako 感谢您的评论。你能扩展一下这个评论吗?我无法真正将其转化为任务/后续步骤。谢谢。
  • 聪明得多的人比我能解释得更好:simple-talk.com/sql/performance/…
  • 因此,索引更新在事务上与 SQL Server 中的数据更新是一致的。过时的索引将指示数据损坏。我并不是说你的性能没有问题,但如果你的索引相对于基础数据已经过时,我会感到惊讶。
  • @dfundako 谢谢,该链接很有帮助

标签: sql-server entity-framework bulkinsert


【解决方案1】:

几年前我们遇到了完全相同的问题。正如 dfundako 所建议的那样,答案是过时的统计数据。 默认情况下,如果一定百分比的记录发生更改,SQLServer 会更新统计信息。如果您的表有大量记录,这是一个问题,因此添加的 90000 条记录不会达到所需的更改行数百分比。 因此,如果您想确定,在插入后您可以重新索引您的表(就像您所做的那样)或更新您的表的统计信息

update statistics <your table>

【讨论】:

  • 事实上,这两个表有 20,000,000 和 5,000,000 行,因此每次更新都将保持在 20% 的阈值以下。
【解决方案2】:

根据此处的 cmets 和答案,我试图弄清楚是否可以以某种方式更改 20% 的阈值。
事实上,有一种方法可以做到这一点,使用trace flag 2371

您可以这样启用它:

DBCC TRACEON(2371, -1)

我现在将等待几周以确保这解决了问题,但我对此抱有很大希望。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    • 2018-07-10
    • 1970-01-01
    • 2016-03-11
    • 1970-01-01
    相关资源
    最近更新 更多