[sql] PostgreSQL에서 정렬을 사용하여 고정 된 수의 행을 삭제하려면 어떻게해야합니까?

이전 MySQL 쿼리를 PostgreSQL로 이식하려고하는데이 쿼리에 문제가 있습니다.

DELETE FROM logtable ORDER BY timestamp LIMIT 10;

PostgreSQL은 삭제 구문에서 순서 나 제한을 허용하지 않으며 테이블에 기본 키가 없으므로 하위 쿼리를 사용할 수 없습니다. 또한 쿼리 가 주어진 숫자 또는 레코드를 정확히 삭제하는 동작을 유지하고 싶습니다. 예를 들어 테이블에 30 개의 행이 포함되어 있지만 모두 동일한 타임 스탬프가있는 경우 중요하지는 않지만 10 개를 삭제하고 싶습니다. 어느 10.

그래서; PostgreSQL에서 정렬을 사용하여 고정 된 수의 행을 삭제하려면 어떻게합니까?

편집 : 기본 키가 없다는 것은 log_id열이나 이와 유사한 것이 없음을 의미 합니다. 아, 레거시 시스템의 기쁨!



답변

다음을 사용해 볼 수 있습니다 ctid.

DELETE FROM logtable
WHERE ctid IN (
    SELECT ctid
    FROM logtable
    ORDER BY timestamp
    LIMIT 10
)

ctid것입니다 :

테이블 내 행 버전의 물리적 위치입니다. 를 ctid사용하여 행 버전을 매우 빠르게 찾을 수 있지만 행이 ctid.NET에 의해 업데이트되거나 이동되면 행 이 변경됩니다 VACUUM FULL. 따라서 ctid장기 행 식별자로 쓸모가 없습니다.

또한 oid테이블을 만들 때 특별히 요청하는 경우에만 존재합니다.


답변

Postgres 문서는 IN 및 하위 쿼리 대신 배열을 사용하도록 권장합니다. 훨씬 빠르게 작동합니다.

DELETE FROM logtable
WHERE id = any (array(SELECT id FROM logtable ORDER BY timestamp LIMIT 10));

이것과 다른 트릭은 여기 에서 찾을 수 있습니다


답변

delete from logtable where log_id in (
    select log_id from logtable order by timestamp limit 10);


답변

순서없이 10 개의 레코드를 삭제한다고 가정하면 다음과 같이 할 수 있습니다.

DELETE FROM logtable as t1 WHERE t1.ctid < (select t2.ctid from logtable as t2  where (Select count(*) from logtable t3  where t3.ctid < t2.ctid ) = 10 LIMIT 1);

내 사용 사례에서 1 천만 개의 레코드를 삭제하면 더 빠른 것으로 판명되었습니다.


답변

개별 행에 대해 삭제를 반복하는 프로 시저를 작성할 수 있으며, 프로시 저는 삭제할 항목 수를 지정하는 매개 변수를 사용할 수 있습니다. 그러나 그것은 MySQL에 비해 약간 과잉입니다.


답변

기본 키가없는 경우 복합 키와 함께 Where IN 구문 배열을 사용할 수 있습니다.

delete from table1 where (schema,id,lac,cid) in (select schema,id,lac,cid from table1 where lac = 0 limit 1000);

이것은 나를 위해 일했습니다.


답변