【问题标题】:delete an entry from a table A if that entry is already present in a table B如果该条目已存在于表 B 中,则从表 A 中删除该条目
【发布时间】:2015-07-02 02:10:46
【问题描述】:

我的问题有点类似于SQL Delete Rows Based on Another Table

除了如果 4 列匹配,则两个条目匹配!

所以,我有:

表1:

Field        | Type             | Null | Key | Default | Extra
f1           | int(32) unsigned | NO   | PRI | NULL    | auto_increment
f2           | int(32)          | NO   |     | 0       |
f3           | int(32)          | NO   |     | 0       | 
f4           | int(32)          | NO   |     | 0       |               

和另一个包含 f1、f2、f3、f4 + 其他字段的表。 我想删除表 1 中与表 2 有对应关系的任何记录,基于

T1.f1=T2.f1 and T1.f2=T2.f2 and T1.f3=T2.f3 and T1.f4=T2.f4

什么是最有效的方法?我虽然在一个程序中检索所有 T1 记录,然后在 T2 上进行 n 次选择,但在 T1 中每次平均有 5k 条记录,我觉得这不是最有效的方式...

编辑: 因为有很多记录,所以我只是在 T2 上的一个字段上创建了一个索引(为了参数的缘故,比如说 field1)

【问题讨论】:

  • 从存在的t1中删除(从t2中选择1 ....)
  • 你用的是什么数据库引擎?
  • 已编辑:我在 oracle dbms 11g 上,一个字段上有一个索引

标签: sql oracle oracle11g


【解决方案1】:

如果要删除的行太多,也可以进行CTAS,即create table as select。从12c 开始,CTAS 不再需要收集统计数据

CTAS 会比 DELETE 快得多。

  • 创建使用 CTAS 方法的新表,其中仅包含所需的行
  • 在这个新表上重新创建所需的索引
  • 删除旧表
  • 重命名新表名到旧表名。

例如,

第 1 步

CREATE TABLE t_new AS
SELECT t1.col1,
  t1.col2,
  t1.col3,
  t1.col4
FROM t1,
  t2
WHERE t1.col1 <> t2.col1
AND t1.col2   <> t2.col2
AND t1.col3   <> t2.col3
AND t1.col4   <> t2.col4;

第 2 步

CREATE INDEX indx_name ON t_new(COLUMN_NAME)

第 3 步

DROP TABLE t1 PURGE;

第 4 步

ALTER TABLE t_new RENAME TO t1;

【讨论】:

    【解决方案2】:

    你可以使用EXISTS:

    DELETE FROM Table1 t1
    WHERE EXISTS
    (
        SELECT 1 FROM Table2 t2
        WHERE T1.f1=T2.f1 AND T1.f2=T2.f2 AND T1.f3=T2.f3 AND T1.f4=T2.f4
    )
    

    最有效的方法取决于您的 rdbms 和使用的索引。

    【讨论】:

    • 我添加了一个编辑:我使用的是 oracle 11g,并且我在其中一个字段上有一个索引。
    • @Phate:您可以在所有涉及的列上创建复合索引,将最具选择性的列放在首位;即值最多的列。
    • 是的,尽管如此,但 T2 可以轻松达到数百万条记录,并且 4 列上的复合索引占用了太多磁盘空间(我已经在 oracle 异常中运行,告诉我保留的磁盘空间已完成)。
    • @TimSchmelter 有时,CTAS 是个好主意,而不是 DELETE。
    • @LalitKumarB:我对 sql-server 比对 oracle 更熟悉。不过谢谢你的提示。
    【解决方案3】:

    在连接中使用删除:

    DELETE t1
    FROM t1
    JOIN t2 ON T1.f1=T2.f1 
      AND T1.f2=T2.f2
      AND T1.f3=T2.f3
      AND T1.f4=T2.f4
    

    作为正确的连接,这种语法通常会产生最佳性能。 T2 中一个(或多个)列的索引会有所帮助。

    【讨论】:

    • 为了提高性能,如果存在适当的主键和外键约束,则连接将仅对父表进行表扫描。
    猜你喜欢
    • 2013-10-25
    • 2013-04-03
    • 1970-01-01
    • 2013-06-27
    • 2016-05-08
    • 1970-01-01
    • 2020-06-29
    • 2011-06-07
    相关资源
    最近更新 更多