【问题标题】:Quick way to reset all column values to a default将所有列值重置为默认值的快速方法
【发布时间】:2010-11-23 07:26:00
【问题描述】:

我正在将数据从一种模式转换为另一种模式。源模式中的每个表都有一个“状态”列(默认为 NULL)。转换记录后,我将状态列更新为 1。之后,我可以报告已(未)转换的记录数。

虽然转换例程仍在开发中,但我希望能够再次快速将状态的所有值重置为 NULL。

表上的 UPDATE 语句太慢(记录太多)。有谁知道实现此目的的快速替代方法?

【问题讨论】:

  • 你在说多少条记录?百万? 10 亿?
  • 大约 7000 万行分布在 217 个表中。

标签: sql oracle plsql


【解决方案1】:

重置列的最快方法是SET UNUSED 列,然后添加具有相同名称和数据类型的列。

这将是最快的方式,因为这两个操作都不会触及实际的表(仅字典更新)。

Nivas' answer 一样,列的实际顺序将被更改(重置列将是最后一列)。如果您的代码依赖于列的顺序(不应该!),您可以创建一个视图,该视图将具有 right 顺序中的列(重命名表,创建与旧表同名的视图,从基表撤消授权,将授权添加到视图)。

SET UNUSED 方法不会回收列使用的空间(而删除列将释放每个块中的空间)。

【讨论】:

  • 这似乎是一条不错的路线。而且我可以在继续工作的同时删除未使用的列。谢谢!
【解决方案2】:

如果该列可以为空(由于默认为NULL,我认为是这种情况),删除并再次添加该列?

【讨论】:

  • 更改表实际上是用临时表来移动数据,并且包括更改数据库结构的开销。不确定这是最优的。
  • +1:简单、高效(@wez 我也不认为删除列会使用临时表来保存数据)
  • 添加 DEFAULT NULL 的列很好,但删除列仍然会移动数据。这适用于 TSQL(sqldev.org/sql-server-database-engine/…) 和 PSQL(postgresql.1045698.n5.nabble.com/… - 请参阅此链接以获取加快速度的调优技巧)
  • @wez:我专门指的是 oracle(来自问题标签:),从the doc 看来,删除一列会更新每一行并且不会将数据复制到临时表。
【解决方案3】:

虽然转换例程仍在开发中,但我希望能够再次快速将状态的所有值重置为 NULL。

如果您正在开发中,为什么需要 7000 万条记录?为什么不针对数据子集进行开发?

【讨论】:

  • 数据来自具有大量异常情况的遗留系统。信任该软件的最佳方式是它是否已成功转换所有数据,而不仅仅是一个子集。
  • @Martin,但希望不是 7000 万个例外情况?您能否构建覆盖已知异常情况的测试数据并在发现新异常时添加?
  • 不,幸运的是没有。尽管如此,使用整个测试集的好处仍然超过构建合理覆盖的测试集的努力。
  • 根据我的经验,能够使用生产规模的数据量进行开发和测试是一件非常好的事情。
【解决方案4】:

你试过使用闪回表吗?

例如:

select current_scn from v$database;
-- 5607722 

-- do a bunch of work

flashback table TABLE_NAME to scn 5607722;

这样做是为了确保每次运行测试时您正在处理的表都是相同的。当然,您需要确保有足够的 UNDO 来保存您的更改。

【讨论】:

    【解决方案5】:

    嗯。可能会在状态列中添加一个索引。

    或者,添加一个仅包含主键的新表。然后在转换记录时插入该表,并 TRUNC 该表以重置...

    【讨论】:

    • 在这种情况下添加索引不会有任何作用,因为必须更新每一行。
    【解决方案6】:

    我喜欢其他一些答案,但我只是在一本调优书中读到,由于多种原因,重新创建表通常比对表进行大量更新更快。在这种情况下,这似乎很理想,因为您将编写 CREATE TABLE X AS SELECT 并希望很少的列。

    【讨论】:

      猜你喜欢
      • 2019-08-17
      • 1970-01-01
      • 2016-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      • 2020-09-01
      • 2013-05-30
      相关资源
      最近更新 更多