programing

다른/변경된 경우 업데이트

powerit 2023. 7. 17. 21:27
반응형

다른/변경된 경우 업데이트

업데이트가 다른 경우에만 SQL에서 업데이트 문을 수행할 수 있습니까?

예를들면

데이터베이스에 있는 경우col1 = "hello"

update table1 set col1 = 'hello'

어떠한 종류의 업데이트도 수행해서는 안 됩니다.

단, 만약

update table1 set col1 = "bye"

업데이트를 수행해야 합니다.

쿼리 컴파일 및 실행 중에 SQL Server는 UPDATE 문이 실제로 값을 변경하는지 여부를 파악하는 데 시간을 들이지 않습니다.필요 없는 경우에도 예상대로 쓰기를 수행합니다.

다음과 같은 시나리오는

update table1 set col1 = 'hello'

SQL이 아무것도 하지 않을 것이라고 생각할 수도 있지만, 실제로 값을 변경한 것처럼 필요한 모든 쓰기 작업을 수행합니다.이 문제는 실제 테이블(또는 클러스터된 인덱스)과 해당 열에 정의된 비클러스터된 인덱스 모두에서 발생합니다.따라서 실제 테이블/인덱스에 쓰기가 발생하고 인덱스 및 트랜잭션 로그 쓰기가 다시 계산됩니다.대용량 데이터 세트로 작업할 경우 변경 사항을 수신할 행만 업데이트하면 성능이 크게 향상됩니다.

필요하지 않을 때 이러한 쓰기 작업의 오버헤드를 방지하려면 업데이트 필요성을 확인하는 방법을 고안해야 합니다.업데이트 필요성을 확인하는 한 가지 방법은 "where col <> 'hello'와 같은 것을 추가하는 것입니다.

update table1 set col1 = 'hello' where col1 <> 'hello'

그러나 예를 들어 행이 많은 테이블에서 여러 열을 업데이트할 때 해당 행의 작은 부분 집합만 실제로 값을 변경하는 경우에는 이 작업이 제대로 수행되지 않습니다.이는 이러한 모든 열을 필터링해야 하는 필요성 때문이며, 일반적으로 동등하지 않은 술어는 위에서 언급한 대로 인덱스 검색과 테이블 & 인덱스 쓰기 및 트랜잭션 로그 항목의 오버헤드를 사용할 수 없습니다.

그러나 EXCUTY 절과 EXCUTY 절을 조합하여 사용하는 훨씬 더 나은 대안이 있습니다.이 방법은 대상 행의 값을 일치하는 원본 행의 값과 비교하여 업데이트가 실제로 필요한지 여부를 확인하는 것입니다.아래 수정된 쿼리를 보고 EXISTS로 시작하는 추가 쿼리 필터를 검토합니다.EXISTES 절 안에 SELECT 문에 FROM 절이 없는 방법을 확인합니다.이 부분은 쿼리 계획에서 지속적인 추가 검색과 필터 작업만 추가하기 때문에 특히 중요합니다(둘 다 비용이 적게 듭니다).따라서 불필요한 쓰기 오버헤드를 방지하면서 처음부터 업데이트가 필요한지 여부를 결정할 수 있는 매우 간단한 방법이 제공됩니다.

update table1 set col1 = 'hello'
/* AVOID NET ZERO CHANGES */
where exists 
    (
    /* DESTINATION */
    select table1.col1
    except
    /* SOURCE */
    select col1 = 'hello'
    )

리터럴 값을 가진 테이블의 모든 행에 대해 하나의 값을 업데이트할 때 원본 질문의 단순 시나리오에 대한 단순 WHERE 절의 업데이트를 확인하는 것과 비교하면 이는 지나치게 복잡해 보입니다.그러나 테이블의 여러 열을 업데이트할 때 업데이트 소스가 다른 쿼리이고 쓰기 및 트랜잭션 로그 항목을 최소화하려는 경우에는 이 방법이 매우 효과적입니다.또한 << 고객명 >>으로 모든 분야를 테스트하는 것보다 성능이 우수합니다.

더 완전한 예는 다음과 같습니다.

update table1
   set col1 = 'hello',
       col2 = 'hello',
       col3 = 'hello'
/* Only update rows from CustomerId 100, 101, 102 & 103 */
where table1.CustomerId IN (100, 101, 102, 103)
/* AVOID NET ZERO CHANGES */
  and exists 
    (
    /* DESTINATION */
    select table1.col1
           table1.col2
           table1.col3
    except
    /* SOURCE */
    select z.col1,
           z.col2,
           z.col3
      from #anytemptableorsubquery z
     where z.CustomerId = table1.CustomerId
    )

새 값이 지금 DB와 동일한 경우 업데이트를 수행하지 않는 것이 좋습니다.

WHERE col1 != @newValue

( 것도 것처럼)가 Id)

WHERE Id = @Id AND col1 != @newValue

'bye'일에만 업데이트를 PS를 추가하면 .AND col1 = 'bye'하지만 전 이게 불필요하다고 생각해요, 제 생각엔

2: ( 2: (으)ㄹ 수 있고, ㄹ 수 있으면 col1이라NULL그래서 만약에NULL가능성이 , 가성이있요어요, ▁it요.WHERE Id = @Id AND (col1 != @newValue OR col1 IS NULL).

를 " 를다로변경려면하으음필드면려변▁the"로 변경하고자 'hello' 에만.'bye'사용:

UPDATE table1
SET col1 = 'hello'
WHERE col1 = 'bye'

이 그것이 .'hello'매개 변수:

UPDATE table1
SET col1 = 'hello'
WHERE col1 <> 'hello'

이런 이상한 접근에 이유가 있나요?했듯이, 이득은 - 과 수천 의 행이 는.col1='hello'그런가요?

업데이트 전 트리거를 사용하면 이 문제가 발생할 수 있습니다.이 트리거에서는 이전 값을 새 값과 비교하고 값이 다르지 않으면 업데이트를 취소할 수 있습니다.하지만 이렇게 하면 발신자의 사이트에 오류가 발생합니다.
왜 이것을 싶은지는 몇 가능성이 : 이런일을하고싶모만지왜, 겠다같몇가있습다니이능성가.

  1. 성능:업데이트는 올바른 행을 찾을 뿐만 아니라 데이터를 추가로 비교해야 하므로 여기서 성능 향상은 없습니다.
  2. 트리거:실제 변경 사항이 있는 경우에만 트리거를 실행하려면 트리거를 실행하여 모든 이전 값을 새 값과 비교한 후 작업을 수행해야 합니다.
CREATE OR REPLACE PROCEDURE stackoverflow([your_value] IN TYPE) AS
BEGIN
   UPDATE   [your_table] t
     SET t.[your_collumn] = [your_value]
   WHERE t.[your_collumn] != [your_value];
  COMMIT;


EXCEPTION
 [YOUR_EXCEPTION];

END stackoverflow;

가 필요합니다.id (과 같은을 합니다.

UPDATE table1 SET col1="hello" WHERE id=1 AND col1!="hello"

요.null가치.

를 사용하면 새 값 할 때 할 수 있습니다. 이 경우 null을 하십시오. <> 또는 !=를 사용하면 가 발생합니다.is distinct fromPostgres의 연산자입니다.자세한 내용은 여기를 참조하십시오.

이 방법이 당신에게 도움이 될 것 같아요

create trigger [trigger_name] on [table_name]
for insert 
AS declare  @new_val datatype,@id int;
select @new_val = i.column_name from inserted i;
select @id = i.Id from inserted i;
update table_name set column_name = @new_val
where table_name.Id = @id and column_name != @new_val;

언급URL : https://stackoverflow.com/questions/6677517/update-if-different-changed

반응형