2016-06-14 11 views
1

VMR 테이블에 마지막 20 개 레코드를 유지하고 다른 모든 레코드를 삭제하고 싶습니다. VMR 테이블에는 5000000 개의 레코드와 레코드가 있습니다. 또한 VMR 테이블에있는 create_date 열이 있고 고유하지 않은 인덱스가 있습니다. rownum을 사용하여 레코드를 삭제하고 아래의 쿼리를 사용하여 최근 20 개의 레코드를 유지하려고 시도했지만 삭제에 너무 많은 시간이 걸렸습니다. 쿼리를 더 빨리 실행할 수있는 다른 방법이 있습니까?최근 20 개의 레코드를 유지하고 oracle sql의 다른 레코드를 삭제하십시오

delete from VMR 
where rowid not in 
     (select rowid 
      from VMR 
     where rownum <=20); 

답변

1

WITH CTE AS (
SELECT t.*, 
     ROW_NUMBER() OVER(ORDER BY create_date DESC) as rnk 
FROM VMR t) 
DELETE FROM CTE 
WHERE CTE.rnk > 20 
+0

쿼리를 설명해 할 수 있습니다? 그것은 나에게 복잡해 보인다. 그리고 나는 결코 쿼리에서 파티션을 사용하지 않았다. – Andrew

+0

실제로 파티션을 사용하지는 않는다.이 파티션은'GROUP BY' 절과 같다. 에 의해 순서대로, 그것은 중요하지 않기 때문에. 이것은 첫 번째 행을 1로, 두 번째를 2 등으로 정렬 한 다음이 데이터로 20보다 큰 모든 것을 삭제합니다. @Andrew – sagi

+0

https://docs.oracle.com/cd/B19306_01/server.102/ b14200/functions137.htm – sagi

3

ROW_NUMBER() 그냥 대체 보여 사용해보십시오 :

-- get 20 last records and remember them 
create table vmr20 as 
    select * from vmr order by create_date desc fetch first 20 rows only; 

-- empty table via DDL which should be fastest 
truncate vmr; 

-- re-insert the last 20 rows 
insert into vmr 
    select * from vmr20; 

-- delete temp table 
drop table vmr20; 
+0

truncate 사용의 단점은 'ROLLBACK'할 수 없다는 것입니다. – MT0

+0

네, 맞습니다. 따라서 잘라 내기 전에 첫 번째 명령문을 실행하지 않도록주의해야합니다 :-) 그리고 테이블이 완전히 비어있는 짧은 시간이 있습니다. 따라서 테이블이 사용되지 않는 시점에이 작업을 수행해야합니다. –