oracle sql-删除每个组的空值行
我尝试删除邮件列中具有空值的行,当且仅当同一个人id存在具有非空值的行时oracle sql-删除每个组的空值行,sql,performance,oracle,Sql,Performance,Oracle,我尝试删除邮件列中具有空值的行,当且仅当同一个人id存在具有非空值的行时 DELETE FROM EMP_MAIL EM WHERE MAIL IS NULL AND EXISTS ( SELECT EMP_ID FROM EMP_MAIL EM2 WHERE MAIL IS NOT NULL AND EM.EMP_ID = EM2.EMP_ID ) ; 但这需要相当长的时间。(我在EMP_邮件上有一个
DELETE
FROM
EMP_MAIL EM
WHERE
MAIL IS NULL
AND EXISTS
(
SELECT
EMP_ID
FROM
EMP_MAIL EM2
WHERE
MAIL IS NOT NULL
AND EM.EMP_ID = EM2.EMP_ID
) ;
但这需要相当长的时间。(我在EMP_邮件上有一个非唯一索引(EMP_ID))
是否有更好的方法执行此操作?这取决于您的输入数据,我希望此查询可以帮助您或为您提供一些解决问题的线索:
DELETE
from
EMP_MAIL t1
where
t1.MAIL is null and
not Exists
(select t2.EMP_ID from (select EMP_ID from EMP_MAIL where mail is not null
minus
select EMP_ID from EMP_MAIL where mail is null)t2 where t1.EMP_ID =t2.EMP_ID);
嗯,我已经做了一些测试,现在我要展示结果 这是我的测试脚本(看看:根本没有索引): 您可以对要删除的行进行处理,然后它执行“delete”语句并删除表 让我们谈谈数字 警告:当我谈论秒时,我的意思是只删除语句,因为行生成器匿名块需要将近2分钟 用这些价值观
amount_of_users constant number := 30000;
nulls_amount_percent constant number := 90;
几乎整个桌子都被删除了,我可以重现你神秘的27.5秒
那我就
amount_of_users constant number := 30000;
nulls_amount_percent constant number := 1;
为了减少删除的行数,它只给我1.8秒的时间
让我们以未删除任何行为例:
amount_of_users constant number := 30000;
nulls_amount_percent constant number := 0;
猜猜时间?1.1秒,据你所说这是你的情况
好吧,我不能给你任何建议去做什么,因为你说的东西可能比一个查询更具全局性。也许,您的数据库版本太旧,或者是关于硬件或其他任何东西
如果是关于这个案子
amount_of_users constant number := 30000;
nulls_amount_percent constant number := 90;
当确实删除了很多行时,我可以建议将删除拆分为10000行部分(首先选择count(*)以了解您应该运行受限删除的次数),并在每次之后进行提交,有时删除大量行要快得多。但就您所说的删除了0行而言,这应该不是您的问题。定义“很长一段时间”。表中有多少行?要删除多少行?表有多大(MB/GB/等)?什么是查询计划?表中有3M行。要删除的0行。30秒。2全表访问。查询良好。3米行30秒也不错。但EMP_ID在表中重复。。为什么不将
EMP\u ID
设为PK,如果MAIL
列必须存储多个值,那么它们有一个单独的表,名为MAIL,其中包含EMP\u ID、MAIL列,然后您可以根据需要将它们连接起来。您可以进一步解释您的逻辑规则吗?@Hamidreza-您的意思是什么?我确实为员工提供了一个不同的表,但出于设计原因,我为每个员工保留了一行,如果没有邮件,我会输入一个空值。我想这会导致三次完整的表扫描(需要检查解释计划),我会投票给OP的查询。
amount_of_users constant number := 30000;
nulls_amount_percent constant number := 0;
amount_of_users constant number := 30000;
nulls_amount_percent constant number := 90;