【问题标题】:Why Would someone Enable Constraint with NoValidate later Validate in Oracle为什么有人会在以后在 Oracle 中验证时使用 NoValidate 启用约束
【发布时间】:2018-01-16 19:21:36
【问题描述】:

我正在通过项目中的程序员编写的一段 Oracle PL-SQL 代码禁用约束,然后先启用“使用 novalidate 启用”,然后立即“验证”它。 我偶然发现了以下块背后的原因:

        EXECUTE IMMEDIATE
               'ALTER TABLE '
            || i_table_name
            || ' ENABLE NOVALIDATE CONSTRAINT '
            || i_constraint_name;

        EXECUTE IMMEDIATE
               'ALTER TABLE '
            || i_table_name
            || ' ENABLE VALIDATE CONSTRAINT '
            || i_constraint_name;

仅将上述内容写在一个语句中有什么问题? 例如:“ALTER TABLE EMP ENABLE EMP_PK”

请解开这个疑问。

【问题讨论】:

    标签: sql database oracle plsql


    【解决方案1】:

    Oracle 在the documentation 推荐这个顺序

    有效使用完整性约束:一个过程

    使用完整性 以下顺序的约束状态可以确保获得最佳收益:

    • 禁用状态。
    • 执行操作(加载、导出、导入)。
    • 启用 novalidate 状态。
    • 启用状态。

    使用约束的一些好处 这个顺序是:

    • 没有持有任何锁。
    • 所有约束都可以同时进入启用状态。
    • 约束启用是并行完成的。
    • 允许在表上进行并发活动。

    【讨论】:

    • 太棒了。非常感谢您的澄清。我现在明白其中的道理了。
    【解决方案2】:

    在实际方面,您可能会面临由于某些数据问题(例如,一种遗留数据迁移问题)遗留/旧数据无法验证的情况,只有新数据。

    在这种情况下,您希望启用约束但将它们设置为 NOVALIDATE。

    这会为未来的数据启用约束,但它不会验证过去的失败(已经在数据库中)。

    当然,这应该是一种临时措施,因为最终您希望修复数据问题,然后使用 VALIDATE 启用约束以避免将来出现类似问题。

    【讨论】:

      【解决方案3】:

      最重要的原因是,“CREATE CONSTRAINT ENABLE VALIDATE”一步完成需要在创建过程中对表进行共享锁。但是对于大型表,验证部分通常需要很长时间。 Oracle 必须确保,即使约束仍未实现,在验证期间也不会插入或修改新的违规数据。

      这可能会对多锁处理产生严重影响。

      另一方面,验证已启用但未验证的索引不需要锁定,因为新数据已针对约束进行检查,并且所有历史数据只需要读取一致性即可验证。 当然,最后需要一个短锁才能最终启用约束。

      至少建议验证检查约束,因为帮助优化器可能很重要。例如。如果验证了 NOT NULL 约束,则优化器可以信任它并为此列选择任何匹配的索引。 如果未验证约束,则可能存在某些具有 NULL 的记录,因此不会被任何索引覆盖。因此,结果可能是全表扫描。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-11
        • 1970-01-01
        • 2021-01-12
        • 2016-06-21
        • 2013-06-01
        • 2023-03-27
        • 1970-01-01
        • 2019-02-24
        相关资源
        最近更新 更多