【问题标题】:unique constraint violated error performance唯一约束违反错误性能
【发布时间】:2014-01-09 16:00:56
【问题描述】:

我在表中插入数百万条记录,这样的操作需要几个小时甚至一天。 2 小时后,通过我的电脑的连接断开了,所以我想从头开始重复插入。
我的问题
哪个更快?截断表并再次重复,创建主键并继续,但是由于过去 2 小时内插入的每条记录都“违反了唯一约束”,将引发错误。 p>

【问题讨论】:

  • 插入效果怎么样?如果已经提交了一些数据,为什么要从头开始重复 - 从第一次没有插入的第一条记录开始不会更有意义? (希望您不是一次插入/提交一行......并且还没有任何索引或触发器)。
  • @AlexPoole 我有一个包含数百万条记录的表,我想将它分成 4 个表。原始表有日期列(第 1 年、第 2 年、第 3 年和第 4 年),因此对于原始表中的每一年,我都将数据插入到表 1 中。所以在我的场景中,我将原始数据插入到 4 个表中。
  • 但是通过什么机制?你是在做insert into new_table_1 select ... from orig_table where year = ...,还是选择所有记录,循环它们,并决定在哪个表中插入每条记录?在什么环境/语言中 - 听起来您可能正在通过网络将整个表拉回您的 PC,然后将其推回四个新表,这将很慢,而不是在数据库中完成所有工作。当然,这并不是你真正要问的。 (你考虑过分区吗?)。
  • @AlexPoole 使用分区将帮助我提高性能,但由于应用程序中的繁忙,将其划分为 4 个表对我有帮助。我是通过游标来做到这一点的 ..fetching 通过主要计数,我包括一个条件,所以它们插入到我正在使用的表中 plsql
  • 对从游标返回的每条记录进行单次插入,或者您是否至少在进行批量插入?只要您有足够的撤消,单个插入(根据您的条件选择)仍然会更快。不过,我已经偏离了滑雪道,问题并不在于它为什么这么慢。如果你在 PL/SQL 中做这件事,你可以提交一个作业来运行它,所以它不依赖于你的客户端被连接。如果您无法从中断的地方继续,截断可能比创建主键(基于什么?)并依赖异常更快。但这有点取决于你走多远。

标签: performance oracle


【解决方案1】:

截断表格(如果完全刷新)是最好的选择。如果您使用 Oracle 的 SQL*Loader 实用程序,还有 SKIP 参数。让我稍微解释一下!

还可以尝试使用 SQL*Loader 使用 DIRECT 加载选项加载表。这意味着通过加载到数据块中来加载表,而不是传统的INSERT 语句。

通过这种加载,您可以启用UNRECOVERABLE,这意味着没有/更少的redo log写入,因此加载速度非常快>70%,比常规INSERT

但是,这种加载的缺点是,除了NULL 约束之外,该表上的所有索引都将在加载开始之前UNUSABLE,并且数据将被加载。在 SUCCESSFUL 完成后,SQL*Loader 会尝试通过重建索引来重新启用它。所以,万一我的任何原因,加载中断,错误消息将被正确记录,索引将被留下UNUSABLE

更多详情:请找Here
(DIRECT/CONVENTIONAL加载中)

另外,使用SQL*Loader,您可以使用Conventional 加载,这意味着SQL*Loader 将使用文件生成插入块,并对其进行处理。在这种类型的加载中,所有 INDEXES 都将保持原样,并且表保持完好。

如果发生任何错误,SQL*Loader 将记录一个 SKIP 参数,这意味着,在下一次运行时,如果您指定该数字,表格将从文件的该点加载。

更多详情SQL*LoaderHere

【讨论】:

  • 我正在运行 pl/sql,所以我不能使用 sql*loader 但是很好的解释。
【解决方案2】:

不确定您是如何加载表的,但这是您应该使用 Oracle 外部表的典型情况。

【讨论】:

  • 你说的外部 oracle 表是什么意思?
  • 总之,使用外部表,可以直接从数据文件中查询数据。转到此documentation 了解更多信息。
猜你喜欢
  • 2020-04-01
  • 2016-07-27
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
  • 2020-02-15
  • 1970-01-01
  • 2011-10-17
  • 2012-03-03
相关资源
最近更新 更多