Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
oracle sql-删除每个组的空值行_Sql_Performance_Oracle - Fatal编程技术网

oracle sql-删除每个组的空值行

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_邮件上有一个

我尝试删除邮件列中具有空值的行,当且仅当同一个人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_邮件上有一个非唯一索引(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;