문제를 해결하는 가장 쉬운 방법은 PostgreSQL에서 자세한 타이밍을 쿼리하는 것 EXPLAIN
입니다. 이를 위해서는 최소한 완료되지만 예상보다 오래 걸리는 단일 쿼리를 찾아야합니다. 이 줄이 다음과 같이 보일 것이라고 가정 해 봅시다.
delete from mydata where id='897b4dde-6a0d-4159-91e6-88e84519e6b6';
실제로 그 명령을 실행하는 대신 할 수 있습니다
begin;
explain (analyze,buffers,timing) delete from mydata where id='897b4dde-6a0d-4159-91e6-88e84519e6b6';
rollback;
결국 롤백을 수행하면 데이터베이스를 실제로 수정하지 않고도이를 실행할 수 있지만 여전히 소요 된 시간에 대한 자세한 타이밍을 얻을 수 있습니다. 이를 실행 한 후 출력에서 일부 트리거로 인해 큰 지연이 발생할 수 있습니다.
...
Trigger for constraint XYZ123: time=12311.292 calls=1
...
는 time
이 contraint을 확인하는 12.3 초 걸렸다 있도록 MS (밀리 초)입니다. INDEX
이 트리거를 효과적으로 계산할 수 있도록 필요한 열에 새 항목을 추가해야합니다 . 외래 키 참조의 경우 다른 테이블을 참조하는 열 (대상 열이 아닌 소스 열)을 색인화해야합니다. PostgreSQL은 이러한 인덱스를 자동으로 생성하지 않으며 DELETE
실제로 해당 인덱스가 필요한 유일한 일반적인 쿼리입니다. 결과적으로 DELETE
인덱스 누락으로 인해 너무 느린 경우에 도달 할 때까지 수년간의 데이터가 누적되었을 수 있습니다 .
해당 제약 조건의 성능을 수정했거나 시간이 오래 걸린 다른 작업이 있으면 begin
/ rollback
블록 에서 명령을 반복 하여 새 실행 시간을 이전과 비교할 수 있습니다. 한 줄 삭제 응답 시간에 만족할 때까지 계속하십시오 (단순히 다른 인덱스를 추가하여 25.6 초에서 15 ms로 이동하는 쿼리가 하나 있습니다). 그런 다음 해킹없이 전체 삭제를 완료 할 수 있습니다.
( EXPLAIN
성공적으로 완료 할 수있는 쿼리 가 필요합니다. PostgreSQL이 한 번의 삭제로 외래 키 제약 조건을 위반하고 EXPLAIN
실패한 경우 타이밍을 방출하지 않기 때문에 사용할 수 없다는 것을 알아 내기 위해 너무 오래 걸린 문제가있었습니다. 이 경우 성능 문제를 쉽게 디버깅 할 수있는 방법을 모르겠습니다.)