【问题标题】:is it safe to perform select by rowid按 rowid 执行选择是否安全
【发布时间】:2013-09-04 15:32:41
【问题描述】:

我想知道使用 rowid 进行行匹配是否安全?

我有以下查询:

select * from a,
    (select a.rowid rid, <some_columns_omitted> from a, b, c where a.some_column = b.some_column ... <joining_omitted>
     union all
     select a.rowid rid, <some_columns_omitted> from a, d, e where a.some_column = d.some_column ... <joining_omitted>
     union all ....) sub_query
where a.rowid = sub_query.rid

使用rowid 进行行匹配会像使用主键一样安全吗?

【问题讨论】:

  • 老实说,这是一个奇怪的问题。您还很可能返回重复项,因为您在子查询中进行了联合(子查询很可能有多行相同的 rowid)。联合或使用 IN 可以解决这个问题,但您是否尝试过根据需要将 a 加入其他表?
  • @tbone,我正在使用这样的查询,因为我需要来自其他表的数据,例如d。由于子查询中的条件,没有重复项,它们不匹配重复项。我无法将联合移出子查询,因为在实际查询中我需要锁定数据,并且我使用了不适用于联合的for update 子句

标签: oracle oracle11g rowid


【解决方案1】:

查看这个相关问题:

Oracle 保证,只要行存在,its rowid does not change。 Rowid 仅在非常特殊的情况下才会更改(表重建、启用行移动的分区表、更新到 pk 的索引组织表)。在堆表上,更新不会导致 rowid 改变,即使行被迁移(因为它不再适合块)。

在任何情况下,rowid 都是行元数据的一部分,并将在查询期间保持一致,与保持列数据一致的 consistency mechanism 相同(多版本读取一致性...)。

此外,如果您锁定行以进行更新(与主键相同),则跨查询使用 rowid 是安全的。通过 rowid 访问行也比主键查找更快(因为主键查找是索引扫描 + rowid 访问)。

【讨论】:

    【解决方案2】:

    我相信使用 rowid 是可以的,但我不喜欢那样。您有一个用于此目的的主键,请使用它。我相信 Oracle 目前保证 rowid 在查询运行期间不会更改,但这是一种不好的做法。例如,如果它运行良好,谁保证在迁移数据库时它会在较新的 Oracle 版本上完美运行?

    【讨论】:

      【解决方案3】:

      如果您认为 Oracle 本身在后台使用 ROWID 来处理查询(想想执行计划中的“TABLE ACCESS BY ROWID”),您最好相信 ROWID 在查询期间是可靠的。 (我还假设读者不会阻止作者,因此 Oracle 在处理记录时不会进行任何特殊锁定。)

      如果是记录 ROWID 以在后续 SQL 语句中使用的情况,那么我会有点谨慎,但对于自包含查询,我会说你会没事的。

      【讨论】:

        猜你喜欢
        • 2020-12-25
        • 2023-03-27
        • 2011-07-11
        • 1970-01-01
        • 2023-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多