2013-07-22 2 views
1

삽입 쿼리 후 수동으로 업데이트 쿼리를 수행하는 것보다 테이블에 삽입 할 때마다 업데이트를 실행하는 트리거가 느려지는지 궁금합니다.데이터베이스 트리거가 쿼리보다 느리게 작동합니까?

+2

트리거 작성 방법에 따라 다릅니다. 확실히 다른 사람이 쓰는 방아쇠를 상상해 볼 수 있습니다.이 방아쇠는 더 나은 쿼리보다 훨씬 효율적이지 않습니다 (방아쇠에 명시 적으로 있는지 여부는 중요하지 않습니다). –

+4

또한 트리거 기능이 플랫폼마다 크게 다를 수 있으므로 플랫폼에 구애받지 않는 포괄적 인 플랫폼이 아니라 우려하는 플랫폼을 대상으로하는 질문을 고려해보십시오. –

답변

1

간단히 말해서 트리거의 실행 계획이 컴파일되어있을 수는 없습니다. 또한이 명령문은 네이티브이므로 명령문을 보내는 데 걸리는 네트워크 대기 시간이 없습니다.

3

다양한 요인에 따라 다릅니다. 첫 번째로, 완전히 다른 3 개의 데이터베이스 제품에 대해 태그를 추가했습니다. 대답은 세 가지 모두 다를 수 있습니다.

오라클 만 고려하면, 영향을받는 행 수와 이것이 테이블의 유일한 트리거인지 여부와 같은 요소에 따라 다릅니다. INSERT 문에 수천 개의 행이 삽입되고 이것이 테이블의 유일한 트리거 일 경우 트리거를 생성하면 수천 개의 SQL이 PL/SQL 컨텍스트로 전환되고 많은 수의 UPDATE 문이 강제로 실행됩니다. 트리거가없는 테이블에 INSERT을 하나 수행하고 그 뒤에 하나의 UPDATE을 입력하면 이러한 모든 컨텍스트 이동을 수행 할 필요가 없어지고 UPDATE 문은 수천 개의 행을 수정하는 데 더 적합한 계획을 사용할 수 있습니다 하나의 행보다 반면에 INSERT 문이 하나의 행을 삽입하는 경우 UPDATE 문에 대한 단일 행 계획을 선호하기 때문에 성능 차이가 거의 없을 수 있으며 한 세트의 컨텍스트 이동 만 수행하면됩니다 .

물론 아키텍처 관점에서 볼 때 다른 문제가있을 수 있습니다. A의 행 레벨 트리거에서 테이블 B를 업데이트하는 것은 일반적으로 다중 사용자 환경에서 올바르게 수행하기 어렵습니다. 많은 로직이 트리거에 묶여 있으면 시스템이 매우 불안정 해지는 경향이 있습니다. 개발자가 변경 사항의 영향을 파악하기 위해 코드를 탐색하기가 어려워 버그와 불일치가 자주 발생합니다. 또한 테이블 A의 삽입이 B를 수정하기 때문에 결국 테이블 변경 예외를 유발하는 일련의 트리거에 의해 삽입 및 업데이트 체인이 생성되는 경우가 자주 발생합니다. 일종의 요약 값을 유지해야하는 경우 (즉, 사용자가 order_items의 행을 수정할 때 orders 테이블의 order_total 열을 업데이트하려는 경우),보다 구체화 된보기가보다 적합한 아키텍처 솔루션 일 수 있습니다. 또는 테이블의 가상 열 또는 계산이 포함 된 뷰에서 더 잘 처리 할 수 ​​있습니다.

+0

+1, 환상적인 답변! 위대한 관측. 그리고이 모든 것을 내 전화로하지 않으면 더 말할 수 있습니다. –

+0

매일 내 홈페이지에서 특정 SO 회원의 답변을 볼 수있는 "따라 가기"버튼을 원합니다 ... – Sebas

+0

@Sebas [아니, 결코 일어나지 않을거야] (http://meta.stackexchange.com/questions/84007)/add-feature-favorite-users). –

4

은 아득히 로 PostgreSQL의가 관련되어 한 번에 하나 개의 행을 업데이트/삽입

, 거의. @Michael이 주장한 네트워크 오버 헤드 때문 만은 아니지만 INSERTUPDATE을 단일 쿼리로 묶을 수 있습니다. writeable CTEs을 고려하십시오./삽입 한 번에 다수의 행 또는 다수의 업데이트

, 는 YES, 그것은 상당히 느릴 수있다. 하나의 명령으로 많은 행을 처리하는 것이 상당히 저렴하므로 x 행에 대한 UPDATE는 트리거에 의해 시작된 x 개별 업데이트보다 훨씬 저렴합니다.

다른 많은 요소가 중요한 역할을하기 때문에 확실하게 말할 수있는 것은 없습니다.내가 the manual here을 인용하고

:

PostgreSQL은 당 행 트리거와 당 문 트리거를 모두 제공합니다. 행당 트리거를 사용하면 행마다 트리거 기능이 트리거되고 트리거를 실행 한 문에 의해이 영향을받습니다.

대담한 강조 광산.

+0

이것은 행이 여러 행 업데이트를 처리하기 위해 트리거가 작성된다는 가정을하지 않습니까? 분명히 트리거의 범위 밖에서 수동으로 실행되는 동일한 쿼리와 동일한 효율성으로 집합 기반 연산을 수행하는 트리거를 작성할 수 있습니다. –

+0

@AaronBertrand : 그렇습니다. 그리고 가정은 올바른 AFAIU 여야합니다. 하나의 행에 의해 시작된 * 모든 * 트리거의 영향은 다음 행에 의해 트리거 된 트리거에서 볼 수 있습니다. 이는 RULE이 대량 작업에 더 빨리 수행 할 수있는 이유 중 하나입니다. 각 명령문 *에 대해 트리거 *를 호출 할 수도 있습니다. 하지만 계단식 업데이트에는 좋지 않습니다. 매뉴얼에서 인용문을 추가했습니다. –

+1

플랫폼에 따라 다릅니다. 모든 시스템이 영향을받은 행당 트리거를 실행하지는 않습니다 (또는 그렇게 할 수도 있습니다). SQL Server에서는이 "상당한"성능 차이를 일으키기 위해 자신의 길을 벗어나야합니다. 사람들을 막을 수는 없으며, 많은 플랫폼을 다루어야하는 그러한 광범위한 질문에 쉽게 대답 할 수있는 것은 아닙니다.* shrug * –

0

이것은 복잡한 질문이며 답변은 데이터베이스에 따라 다를 수 있습니다.

일반적으로 트리거는 적어도 하나의 행이 포함될 때 별도의 업데이트를 수행하는 것보다 빠르다는 것을 기대합니다. 그러나 여러 행을 삽입 할 때 상황이 다를 수 있습니다. 이 경우 일부 데이터베이스는 트리거를 한 번에 여러 행으로 호출합니다. 일부 데이터베이스는 각 행에 대해 한 번씩 여러 번 트리거를 호출합니다.

후자의 경우 동시에 여러 작업을 수행하면 더 빠른 코드를 작성할 수 있습니다.

또 다른 고려 사항은 처리량입니다. 방아쇠가있는 조작이 더 빠를 수도 있습니다. 그러나 테이블이나 행을 더 긴 시간 동안 잠궈 테이블의 다른 조치를 막을 수도 있습니다. 인터리브 된 데이터베이스 호출이 더 긴 호출보다 빠르다는 것을 알 수 있습니다.

그런 질문을하는 경우, 제 제안은 당신이 타이밍을내는 것입니다. 다른 데이터베이스에서 결과가 동일 할 것으로 예상하지 마십시오. 데이터베이스 엔진은 공통점이 많지만 잠금 및 트랜잭션에 대한 세부 사항을 다루고 있으며 이는 공급 업체마다 다릅니다.

관련 문제