【问题标题】:Oracle : Identifying duplicates in a table without indexOracle:在没有索引的表中识别重复项
【发布时间】:2011-01-30 12:48:43
【问题描述】:

当我尝试在大表上创建唯一索引时,我收到了唯一约束错误。在这种情况下,唯一索引是 4 列的组合键。

除了:

之外,有没有一种有效的方法来识别重复项?
select col1, col2, col3, col4, count(*)
from Table1
group by col1, col2, col3, col4
having count(*) > 1

上面的explain plan显示了全表扫描,代价非常高,只是想看看有没有别的办法。

谢谢!

【问题讨论】:

标签: oracle plsql duplicates


【解决方案1】:

首先尝试在这四列上创建一个非唯一索引。这将花费 O(n log n) 时间,但也会将执行 select 所需的时间减少到 O(n log n)。

您在这里有点麻烦 - 无论您以何种方式对其进行切片,都必须至少读取整个表一次。朴素算法的运行时间为 O(n2),除非查询优化器足够聪明,可以构建临时索引/表。

【讨论】:

  • 解决非唯一问题后,您可以使用您创建的非唯一索引强制执行唯一约束。它不会让您在同一列上有非唯一索引时创建唯一索引,因此如果您真的想要唯一索引,请在 table1(col1,col2,col3) 上创建非唯一索引作为创建索引 t_ix ,col4,1);最后使用文字,它不会阻止您稍后在 col1,col2,col3,col4 上创建唯一索引,然后删除非唯一索引
  • 所有回复都表明没有简单的方法可以解决这个问题。但是这个答案也给了我一个方法,所以我选择这个作为我的问题的最佳答案。谢谢杰夫。
【解决方案2】:

您可以使用 EXCEPTIONS INTO 子句来捕获重复的行。

如果您还没有 EXCEPTIONS 表,请使用提供的脚本创建一个:

SQL>  @$ORACLE_HOME/rdbms/admin/ultexcpt.sql

现在你可以尝试像这样创建一个唯一的约束

alter table Table1
add  constraint tab1_uq UNIQUE (col1, col2, col3, col4)
exceptions into exceptions
/

这将失败,但现在您的 EXCEPTIONS 表包含键包含重复项的所有行的列表,由 ROWID 标识。这为您决定如何处理重复项(删除、重新编号等)提供了依据。

编辑

正如其他人所指出的,您必须支付一次扫描表的费用。这种方法为您提供了一组永久的重复行,而 ROWID 是访问任何给定行的最快方法。

【讨论】:

    【解决方案3】:

    由于这些列上没有索引,因此该查询必须执行全表扫描 - 没有其他方法可以真正做到这一点,除非其中一个或多个列已被索引。

    您可以将索引创建为非唯一索引,然后运行查询以识别重复的行(创建索引后应该非常快)。但我怀疑创建非唯一索引然后运行查询的总时间是否会比只运行没有索引的查询要少。

    【讨论】:

      【解决方案4】:

      事实上,您需要查找表中每一行的副本。没有索引就无法有效地做到这一点。

      【讨论】:

        【解决方案5】:

        不幸的是,我认为没有更快的方法。

        【讨论】:

          猜你喜欢
          • 2021-01-03
          • 2011-11-16
          • 1970-01-01
          • 2021-11-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多