提高oracle删除查询性能

时间:2014-01-07 16:01:53

标签: sql oracle performance sql-delete

这是我的查询,我计划分批运行它,因此rownum< 5000

delete my_table
where  rownum < 5000 
and    type = 'Happy'
and    id not in 
       ( select max_id
         from   ( select max(log_id) max_id
                  ,      object_id
                  ,      type
                  from   my_table
                  where  type = 'Happy'
                  group
                  by     id
                  ,      type
                )
        )

我想删除快乐记录,但保留最大日志ID,每个对象ID

我希望这是有道理的。

我应该使用某种联接来提高性能吗?

3 个答案:

答案 0 :(得分:3)

我认为这可能会作为相关子查询运行得更快:

Delete
    from my_table
    where type = 'Happy' and
          exists (select 1
                  from my_table t2
                  where t2.object_id = my_table.object_id and
                        t2.type = my_table.type and
                        t2.id > my_table.id
                 );

然后,my_table(object_id, type, id)上的索引也可能有助于此查询。

答案 1 :(得分:0)

由于你只想删除type ='Happy'的任何5000个日志条目,只要它不是任何object_id的最新条目,那么你可以这样做:

delete
from my_table
where log_id in (
    select log_id from (
        select log_id, 
            row_number() over (partition by object_id order by log_id desc) rnk
        from my_table
        where typ = 'Happy' 
        and rownum <= 5000
    )
    where rnk > 1
)

这与您的方法不同,因为在您的方法中,您仍然需要计算整个表中每个对象的max(id),这是不必要的(并且日志表会变得非常大)。您只需要确保不删除5000批次行的“最新”行(每个对象)。就个人而言,我更喜欢使用分区设置日志表,但不是每个人都有此选项。

希望有所帮助。

答案 2 :(得分:0)

您可以将查询简化为:

delete my_table
where  rownum < 5000 
and    type = 'Happy'
and    id not in (select   max(log_id) max_id
                  from     my_table
                  where    type = 'Happy'
                  group by object_id, type)