当前位置: 首页 > 知识库问答 >
问题:

从一个表中删除连接到另一个表中的记录

徐星阑
2023-03-14

我有两个表,一个有212,000条记录(不推荐使用的记录),另一个有10,500,000条记录

在删除记录之前使用外部联接有意义吗?我在想,如果可能的话,这可以帮助我跟踪被删除的内容

共有1个答案

曾修真
2023-03-14

您不需要使用outer join,只需要检查将返回多少行。不会被删除。

下面是这样的查询示例(我使用在答案末尾提供的生成的测试数据)

with del as (
select delta.id, delta.version,
decode(big.id,null,0,1) is_deleted
from delta
left outer join big 
on delta.id = big.id and delta.version = big.version
)
select is_deleted, count(*) cnt, max(id||'.'||version) eg_id_vers
from del
group by is_deleted;

IS_DELETED        CNT  EG_ID_VERS                                                                   
---------- ---------- ----------
         1      20000 99995.0   
         0         20 100100.0   

根据您的数据大小,您应该在两个表上使用hash joinfull table scan,以获得可接受的性能

create unique index delta_idx on delta(id,version);

相反,大表不应该有这样的约束。这很重要,因为它清楚地表明您的BIG table是join视图中唯一一个保留键的表。

简单地将一个连接放到小表中不能复制大表中的行,因为这是一个独特的反差

有关更新联接视图的详细信息,请参阅此处

delete from 
(
select delta.id, delta.version, big.id big_id, big.version
from big 
join delta 
on delta.id = big.id and delta.version = big.version
)
DELETE FROM big 
    WHERE EXISTS (SELECT null
                  FROM delta
                  WHERE delta.id = big.id and delta.version = big.version
                 ) 

不需要索引,您应该期待一个带有哈希联接右半的执行计划,这意味着这两种方法实际上并没有什么不同。

测试样本数据

create table big as
select 
trunc(rownum/10) id, mod(rownum,10) version,
lpad('x',10,'Y') pad
from dual connect by level <= 1000000;

/* the DELTA table has 50 times less rows,
allow some rows out of range of the BIG table - those rows will not be deleted **/
drop table delta;
create table delta as
select 
trunc(rownum*50/10) id, mod(rownum*50,10) version
from dual connect by level <= 1001000/50;

create unique index delta_idx on delta(id,version);
 类似资料:
  • 问题内容: 我有两个看起来像这样的表: 表:案例 id 名称 状态 case_no 表:注意事项 id case_id note_date 注释 我希望能够创建一个查询,以从案例表中获取数据,并仅从注释表中获取案例表中每一行的最新条目。到目前为止,我根本没有运气。 任何指针将不胜感激 问题答案: 这只会返回带有注释的案例: 如果需要所有案例,无论是否附带注释:

  • 我想从两个表中删除相关的行。可能有外键,也可能没有。因此,可以肯定的是,我不想依赖外键及其在DELETE上的

  • 问题内容: 我有以下两个表(在MySQL中): 如何找出哪些电话是由人,他们提出是不是在?所需的输出将是: 问题答案: 有几种不同的方法可以执行此操作,效率各不相同,具体取决于查询优化器的性能以及两个表的相对大小: 这是最简短的陈述,如果您的电话簿很短,则可能是最快的陈述: 或(感谢WOPR) (忽略这一点,正如其他人所说的那样,通常最好只选择所需的列,而不是’ ‘)

  • 问题内容: 我有看起来像这样的数据: 流程将定期运行并为每个实体评分。该过程将生成数据并将其添加到得分表中,如下所示: 我希望能够为每个实体选择所有实体以及最新记录的分数,从而得到如下所示的一些数据: 我可以使用以下查询获取单个实体的数据: 但是我不知道如何为所有实体选择相同的内容。也许它正盯着我看? 非常感谢您抽出宝贵的时间。 感谢您的好评。我将花几天时间查看首选解决方案是否冒泡,然后选择答案。

  • 问题内容: 我试图根据另一个数据库的选择标准从一个数据库中删除记录。我们有两个表,emailNotification,用于存储作业和电子邮件列表。然后我们有工作。我想清除已关闭作业的emailNotifications。我在Stackoverflow上找到了一些较早的示例,这些示例将我带到了这种语法类型(我以前曾尝试在where之前进行连接)。 我收到错误消息,您无法在FROM子句中指定目标表’e

  • 我正在从远程数据库读取一组行,从本地数据库读取一组类似的行,然后使用RemoveAll删除本地已经存在的远程行。。。 但这对我来说似乎不对。当我真正需要做的只是检查是否存在匹配项时,我认为我不应该计算事物。我尝试了和的各种用法,但得到了废话。我不能使用(如这里建议的),因为列表元素不是同一类型。 有更好的方法吗?