복붙노트

[SQL] SQL에서 UPDATE가 DELETE +의 INSERT보다 항상 빠른?

SQL

SQL에서 UPDATE가 DELETE +의 INSERT보다 항상 빠른?

나는 다음과 같은 필드가 간단한 테이블을 가지고 말 :

내 응용 프로그램은 항상 이름 필드 작업을 기반으로하기 때문에 나는, 조회의 ID 필드를 사용하지 않습니다.

나는 때때로 태그 값을 변경해야합니다. 나는 다음과 같은 사소한 SQL 코드를 사용하고 있습니다 :

UPDATE Table SET Tag = XX WHERE Name = YY;

사람이 위의 것보다 항상 더 빨리인지 알고 있다면 궁금 :

DELETE FROM Table WHERE Name = YY;
INSERT INTO Table (Name, Tag) VALUES (YY, XX);

다시 - 나는 두 번째 예에서 ID가 변경된 것을 알고 있지만, 내 응용 프로그램에 대한 문제가되지 않습니다.

해결법

  1. ==============================

    1.A는이 답변에 너무 늦게 비트,하지만 비슷한 질문을 직면하기 때문에, 나는 JMeter를 사용하여 테스트 내가 사용했던 동일한 시스템에 MySQL 서버를 만든 :

    A는이 답변에 너무 늦게 비트,하지만 비슷한 질문을 직면하기 때문에, 나는 JMeter를 사용하여 테스트 내가 사용했던 동일한 시스템에 MySQL 서버를 만든 :

    500 개 루프에 대한 테스트를 실행 한 후, 나는 다음과 같은 결과를 얻었다 :

    DEL + INSERT - 평균 : 62ms

    업데이트 - 평균 : 30ms의

    결과 :

  2. ==============================

    2.테이블 (의 수와 열의 크기)은 삭제 및 업데이트보다는 삽입된다 더 비싼 더 큰. 당신은 UNDO 및 REDO의 가격을 지불해야하기 때문에. 삭제 작업 UPDATE들보다 더 UNDO 공간을 소비하고 많은 문으로 필요로 REDO 두 번이 포함되어 있습니다.

    테이블 (의 수와 열의 크기)은 삭제 및 업데이트보다는 삽입된다 더 비싼 더 큰. 당신은 UNDO 및 REDO의 가격을 지불해야하기 때문에. 삭제 작업 UPDATE들보다 더 UNDO 공간을 소비하고 많은 문으로 필요로 REDO 두 번이 포함되어 있습니다.

    게다가, 비즈니스 관점에서 명백히 잘못이다. 그것은 그 테이블에 개념적인 감사 추적을 이해하는 것이 얼마나 더 힘들어 고려하십시오.

    그것은 이전 테이블에서 CTAS를 사용하여 (SELECT 절의 투사에 업데이트를 적용), 이전 테이블을 삭제하고 이름을 변경하여 새 테이블을 만들 빠른 테이블의 모든 행의 대량 업데이트를 포함하는 몇 가지 시나리오가 있습니다 새 테이블. 부작용은 제약을 관리하고 권한을 갱신, 인덱스를 만드는,하지만 고려 가치가있다.

  3. ==============================

    3.같은 행에 하나 개의 명령은 항상 동일한 행에 빠르게 두 이상이어야한다. 그래서 업데이트는 더 좋을 것이다.

    같은 행에 하나 개의 명령은 항상 동일한 행에 빠르게 두 이상이어야한다. 그래서 업데이트는 더 좋을 것이다.

    편집하다 테이블을 설정합니다 :

    create table YourTable
    (YourName  varchar(50)  primary key
    ,Tag int
    )
    
    insert into YourTable values ('first value',1)
    

    내 시스템 (SQL 서버 2005)에 1 초 걸립니다,이 실행 :

    SET NOCOUNT ON
    declare @x int
    declare @y int
    select @x=0,@y=0
    UPDATE YourTable set YourName='new name'
    while @x<10000
    begin
        Set @x=@x+1
        update YourTable set YourName='new name' where YourName='new name'
        SET @y=@y+@@ROWCOUNT
    end
    print @y
    

    내 시스템에 2 초 발생한,이 실행 :

    SET NOCOUNT ON
    declare @x int
    declare @y int
    select @x=0,@y=0
    while @x<10000
    begin
        Set @x=@x+1
        DELETE YourTable WHERE YourName='new name'
        insert into YourTable values ('new name',1)
        SET @y=@y+@@ROWCOUNT
    end
    print @y
    
  4. ==============================

    4.나는 당신의 질문의 몸이 제목 질문에 관련이 두렵다.

    나는 당신의 질문의 몸이 제목 질문에 관련이 두렵다.

    제목을 대답하는 경우 :

    다음 대답은 NO입니다!

    그냥 구글

    직접 삽입 + 업데이트보다 삽입 + 업데이트를 통해 업데이트 더 비싼 (기타 처리) 실현 이러한 갱신은 결과. 이러한 사건 때이다

    내 빠른이 (비 철저한) 검색을 포함하는 척하지, 나에게 준 [1], [2]

    [1] 업데이트 작업 (Sybase® SQL 서버 성능 및 조정 설명서 장 7 : SQL Server 쿼리 최적화) http://www.lcard.ru/~nail/sybase/perf/11500.htm [2] UPDATE 문은 DELETE /의 INSERT 쌍으로 복제 될 수 http://support.microsoft.com/kb/238254

  5. ==============================

    5.마음에 DELETE +의 INSERT가 시간에 따라 큰 차이를 만들 것입니다 올바르게 구현 UPDATE에 반대 발행 될 때 발생하는 실제 조각을 유지합니다.

    마음에 DELETE +의 INSERT가 시간에 따라 큰 차이를 만들 것입니다 올바르게 구현 UPDATE에 반대 발행 될 때 발생하는 실제 조각을 유지합니다.

    삽입 INTO ... ON DUPLICATE KEY UPDATE ... 구문을 사용하여 반대로 그게 왜, 예를 들어, MySQL의 구현이 좌절되는 것을 INTO를 교체합니다.

  6. ==============================

    6.그냥 44 개 필드와 테이블에 43 개 필드를 업데이트하는 시도, 나머지 필드는 기본 클러스터 키이었다.

    그냥 44 개 필드와 테이블에 43 개 필드를 업데이트하는 시도, 나머지 필드는 기본 클러스터 키이었다.

    업데이트 8 초 걸렸습니다.

    삭제 + 삽입 빠른 최소 시간 간격보다 그 SQL Management Studio를 통해 "클라이언트 통계"보고서.

    베드로

    MS SQL 2008

  7. ==============================

    7.귀하의 경우에는, 나는 업데이트가 빠를 것으로 판단된다.

    귀하의 경우에는, 나는 업데이트가 빠를 것으로 판단된다.

    인덱스를 기억하십시오!

    당신은 (적어도 SQL Server가 그렇게)가 가능성이 자동으로 클러스터 된 인덱스 될 것입니다, 기본 키를 정의했습니다. 클러스터 인덱스 레코드가 물리적으로 인덱스에 따라 디스크에 배치하는 것을 의미한다. 삭제 작업 자체가 하나 개의 레코드가 사라질 후에도, 인덱스 숙박은 수정, 많은 문제가 발생하지 않습니다. 새 레코드를 삽입 할 때 단, DB 엔진은 새로운 하나 "화장 장소"일부 오래된 레코드 "재편"을 발생합니다 상황에서하는 올바른 위치에이 기록을 넣어해야합니다. 이 작업을이 둔화 될 경우.

    값이 계속 증가하는 경우 새 레코드 그냥 꼬리에 추가 얻을 수 있도록 인덱스 (특히 클러스터)는 가장 잘 작동합니다. 어쩌면 당신은 클러스터 된 인덱스가되기 위해 별도의 INT의 IDENTITY 열을 추가 할 수 있습니다,이 작업을 삽입 간소화됩니다.

  8. ==============================

    8.속도의 문제는 특정 속도 문제없이 무관하다.

    속도의 문제는 특정 속도 문제없이 무관하다.

    기존 행을 변경하기 위해 SQL 코드를 작성하는 경우, 당신은 그것을 업데이트합니다. 다른 건 올바르지 않습니다.

    당신이 코드가 작동하는 방법의 규칙을 깰려고하는 경우에, 당신은 더 나은 빌어 먹을 좋은, 그것에 대한 정량화 된 이유, 그리고 "이 방법은 더 빨리", 당신이 없을 때 어떤 막연한 생각이있을 것이다 아이디어는 "더 빨리"것입니다.

  9. ==============================

    9.당신은 몇 백만 행을 어떤이있는 경우. 각 행은 하나의 데이터, 아마도 클라이언트 이름으로 시작합니다. 당신이 클라이언트에 대한 데이터를 수집 할 때, 해당 항목을 업데이트해야합니다. 자,하자의 클라이언트 데이터의 수집이 나중에 수집하고 데이터베이스에 투입되는 수많은 다른 컴퓨터에 분산되어 있다고 가정합니다. 각 클라이언트가 고유 정보가있는 경우, 당신은 대량 업데이트를 수행 할 수 없을 것입니다; 당신이 한 번에 여러 클라이언트를 업데이트하는 데 사용하는 즉, 어떤 절 기준이 없습니다. 다른 한편으로는, 당신은 대량 삽입을 수행 할 수 있습니다. 더 나은 단일 업데이트의 수백만을 수행하는 것입니다, 또는 큰 대량 삭제 및 삽입로를 컴파일하는 것이 좋습니다 : 그래서, 질문은 더 나은 다음과 같이 제기 될 수 있습니다. milltion이 시간, 당신은 '[표]에서 삭제합니까 "클라이언트 ID = 123 갱신 [표] 세트 필드 = 데이터"대신 즉,에서 클라이언트 ID ([모든 클라이언트를 업데이트해야합니다]) 여기서 [표]에 삽입 값 (CLIENT1 데이터) (CLIENT2 데이터) 등 '

    당신은 몇 백만 행을 어떤이있는 경우. 각 행은 하나의 데이터, 아마도 클라이언트 이름으로 시작합니다. 당신이 클라이언트에 대한 데이터를 수집 할 때, 해당 항목을 업데이트해야합니다. 자,하자의 클라이언트 데이터의 수집이 나중에 수집하고 데이터베이스에 투입되는 수많은 다른 컴퓨터에 분산되어 있다고 가정합니다. 각 클라이언트가 고유 정보가있는 경우, 당신은 대량 업데이트를 수행 할 수 없을 것입니다; 당신이 한 번에 여러 클라이언트를 업데이트하는 데 사용하는 즉, 어떤 절 기준이 없습니다. 다른 한편으로는, 당신은 대량 삽입을 수행 할 수 있습니다. 더 나은 단일 업데이트의 수백만을 수행하는 것입니다, 또는 큰 대량 삭제 및 삽입로를 컴파일하는 것이 좋습니다 : 그래서, 질문은 더 나은 다음과 같이 제기 될 수 있습니다. milltion이 시간, 당신은 '[표]에서 삭제합니까 "클라이언트 ID = 123 갱신 [표] 세트 필드 = 데이터"대신 즉,에서 클라이언트 ID ([모든 클라이언트를 업데이트해야합니다]) 여기서 [표]에 삽입 값 (CLIENT1 데이터) (CLIENT2 데이터) 등 '

    다른 것보다 중 하나를 선택 나은가, 아니면 두 가지를 망했다?

  10. ==============================

    10.물론, 대답은 당신이 사용하고있는 데이터베이스를 기반으로 다르지만, UPDATE는 항상 빠른 DELETE +의 INSERT에 비해 구현 될 수있다. 메모리 내 작전은 하드 드라이브 기반 데이터베이스 제공, 어쨌든 대부분 사소한 때문에 삭제가 행 (빈 공간을 떠나)을 제거하고 새를 삽입 할 때, 업데이트가, 하드 디스크에 현재 위치에서 데이터베이스 필드를 변경할 수 있습니다 아마 테이블 (다시, 그것은 구현에 전부)의 끝에, 행.

    물론, 대답은 당신이 사용하고있는 데이터베이스를 기반으로 다르지만, UPDATE는 항상 빠른 DELETE +의 INSERT에 비해 구현 될 수있다. 메모리 내 작전은 하드 드라이브 기반 데이터베이스 제공, 어쨌든 대부분 사소한 때문에 삭제가 행 (빈 공간을 떠나)을 제거하고 새를 삽입 할 때, 업데이트가, 하드 디스크에 현재 위치에서 데이터베이스 필드를 변경할 수 있습니다 아마 테이블 (다시, 그것은 구현에 전부)의 끝에, 행.

    다른 사소한, 문제는 단일 행에 하나의 변수를 업데이트 할 때, 해당 행의 다른 컬럼이 동일하게 유지한다는 것이다. 삭제 한 다음 INSERT를 할 경우, 당신은 다른 열 잊고 결과적으로 그들을 뒤에 떠나는 위험을 실행합니다 (이 경우 당신이 전에 선택을해야 할 것입니다 귀하의 일시적 다시 INSERT와를 쓰기 전에 다른 열을 저장하는 DELETE) .

  11. ==============================

    11.업데이트가 포함 된 방법으로 더 많은 단계가 있기 때문에 + 삽입은 항상 빠른 거의이다 삭제합니다.

    업데이트가 포함 된 방법으로 더 많은 단계가 있기 때문에 + 삽입은 항상 빠른 거의이다 삭제합니다.

    최신 정보:

    + 삽입 삭제 :

    삽입 + 삭제를 사용하면 파일 시스템 단편화,하지만 그렇게 빨리 것입니다. 배경에 게으른 최적화를 수행하면 무료로 사용되지 않는 블록에 allways하고 모두 테이블을 포장합니다.

  12. ==============================

    12.이 제품에 따라 달라집니다. 제품은 (내부적으로) 그 구현 DELETE 및 INSERT A (트랜잭션 포장)에 모든 업데이트를 변환 할 수있다. 제공된 결과는 UPDATE 의미와 일치한다.

    이 제품에 따라 달라집니다. 제품은 (내부적으로) 그 구현 DELETE 및 INSERT A (트랜잭션 포장)에 모든 업데이트를 변환 할 수있다. 제공된 결과는 UPDATE 의미와 일치한다.

    나는이 작업을 수행하는 모든 제품의 알고 있어요 말하는 게 아니에요,하지만 완벽하게 합법적이다.

  13. ==============================

    13.데이터베이스에 대한 모든 쓰기는 잠재적 인 부작용이 많이 있습니다.

    데이터베이스에 대한 모든 쓰기는 잠재적 인 부작용이 많이 있습니다.

    삭제 : 행은 제거되어야한다, 인덱스 업데이트, 외래 키는 확인하고 가능성 등 캐스케이드 - 삭제 삽입 : 행이 할당되어야합니다 -이 삭제 된 행의 장소에있을 수 있습니다,하지 않을 수도 있습니다; 인덱스를 업데이트해야합니다, 외래 키 체크 등 업데이트 : 하나 이상의 값을 업데이트해야합니다; 아마도 행의 데이터가 더 단편화 블록에 재 기입, 또는 리드 인 다수의 블록으로 계단식 수 많은 공간이 할당되어야하므로 데이터베이스의 블록으로 더 적합;하지 값이 외래 키 제약 조건이있는 경우 그들은 등을 확인해야

    열 매우 적은 수의 또는 전체 행이 갱신되는 경우 삭제 + 삽입을 위해 더 빠를 수 있지만, FK 제약 문제는 큰 하나입니다 수 있습니다. 물론, 어쩌면 당신은 이제 더 FK 제약이 없다, 그러나 그것은 항상 사실이 될 것인가? 당신이 트리거가있는 경우 그리고 핸들 업데이트가 업데이트 작업이 진정으로 업데이 트이면 것을 코드를 작성하는 것이 더 쉽습니다.

    에 대해 생각하는 또 다른 문제는 업데이트보다 때로는 삽입 및 삭제 보류 다른 잠금입니다. 삽입하거나 삭제하는 동안 그 기록을 갱신하는 동안 단 하나의 기록을 잠금 반대로 DB는 전체 테이블을 잠글 수 있습니다.

    결국, 당신이 그것을 업데이트 할 말은 경우에 단지 기록을 갱신하는 게 좋을 것. 그런 다음 만들어 질 성능 향상이 있는지 확인하기 위해 DB의 성능 통계 및 해당 테이블에 대한 통계를 확인합니다. 다른 건 시기상조이다.

    우리는 두 단계 접근 방식에 데이터베이스에 신용 카드 거래 데이터를 저장했다 :의 전자 상거래 시스템 I 작업에서 예 첫째, 우리는 과정을 시작했음을 나타냅니다 부분 트랜잭션을 작성합니다. 그런 다음, 권한 부여 데이터가 은행에서 반환 될 때 기록을 업데이트합니다. 우리는 다음 삭제 한 수 기록을 다시 삽입 대신 우리는 단지 업데이 트를 사용했다. 우리의 DBA는 테이블이 DB는 각 행에 대해 작은 공간을 할당했기 때문에 조각난, 그것은 많은 데이터를 추가하기 때문에 업데이트가 블록 체인의 원인이되었다라고 우리에게 이야기했다. 그러나 오히려 스위치보다 우리가 항상이 방법은 업데이트가 문제없이 미리 할당 된 빈 공간을 사용할 수있는 전체 행을 할당하기 위해 데이터베이스를 조정 + INSERT를 삭제합니다. 어떤 코드 변경이 필요하지 않으며, 코드는 간단하고 이해하기 쉽게 남아있다.

  14. ==============================

    14.특정 경우에, 삭제 + 삽입 시간을 절약 할 것이다. 나는 30000 개 홀수 행을 가지고 있으며, 데이터 파일을 사용하여 이러한 기록을 매일 갱신 / 삽입이 테이블을 가지고있다. 레코드가 이미 존재하지 않는 사람을위한 삽입물의 5 %만큼 업로드 과정은 UPDATE 문의 95 %를 생성합니다. 대안 적으로, 임시 테이블로 데이터 파일의 기록을 업로드, 임시 테이블의 레코드의 대상 테이블의 삭제는 시간의 50 % 증가를 보였다 임시 테이블에서 동일한 삽입 하였다.

    특정 경우에, 삭제 + 삽입 시간을 절약 할 것이다. 나는 30000 개 홀수 행을 가지고 있으며, 데이터 파일을 사용하여 이러한 기록을 매일 갱신 / 삽입이 테이블을 가지고있다. 레코드가 이미 존재하지 않는 사람을위한 삽입물의 5 %만큼 업로드 과정은 UPDATE 문의 95 %를 생성합니다. 대안 적으로, 임시 테이블로 데이터 파일의 기록을 업로드, 임시 테이블의 레코드의 대상 테이블의 삭제는 시간의 50 % 증가를 보였다 임시 테이블에서 동일한 삽입 하였다.

  15. ==============================

    15.대량 삭제 / 벌크 삽입 대 개별 업데이트 많은 수의 내 scenario.I 백 년가는 여러 고객의 과거 판매 데이터를 가지고있다. 나는 검증 데이터 (다음 달 15 일) 때까지, 나는 (이 수단이 매출의 대부분 사십오일 각 고객에 대한 각각의 날에 덮어 쓰기) 다른 소스에서 얻은 현재 상태를 반영하기 위해 매일 판매 수를 조정합니다. 변경이 없을 수도 있고, 약간의 변화가있을 수 있습니다. 나도 코드 논리는 영향을받는 레코드를 삽입 차이 및 업데이트 / 삭제 /를 찾을 수 있습니다 또는 그냥 어제의 숫자와 오늘의 숫자 삽입을 날려 버릴 수 있습니다. 분명 후자의 접근 방식은 간단하지만이 때문에 이탈에 테이블의 성능을 죽일거야 있다면, 그것의 가치는 그 삽입 소수 (또는 없음) 레코드의 변경 것으로 만 업데이트 / 삭제 /을 식별 할 수있는 별도의 로직을 작성 할 수 있습니다.

    대량 삭제 / 벌크 삽입 대 개별 업데이트 많은 수의 내 scenario.I 백 년가는 여러 고객의 과거 판매 데이터를 가지고있다. 나는 검증 데이터 (다음 달 15 일) 때까지, 나는 (이 수단이 매출의 대부분 사십오일 각 고객에 대한 각각의 날에 덮어 쓰기) 다른 소스에서 얻은 현재 상태를 반영하기 위해 매일 판매 수를 조정합니다. 변경이 없을 수도 있고, 약간의 변화가있을 수 있습니다. 나도 코드 논리는 영향을받는 레코드를 삽입 차이 및 업데이트 / 삭제 /를 찾을 수 있습니다 또는 그냥 어제의 숫자와 오늘의 숫자 삽입을 날려 버릴 수 있습니다. 분명 후자의 접근 방식은 간단하지만이 때문에 이탈에 테이블의 성능을 죽일거야 있다면, 그것의 가치는 그 삽입 소수 (또는 없음) 레코드의 변경 것으로 만 업데이트 / 삭제 /을 식별 할 수있는 별도의 로직을 작성 할 수 있습니다.

    그래서, 기록을 대체하고있어, 및 이전 기록과 새로운 기록 사이에 관계가있을 수 있지만, 일반적으로 내가 반드시 새 데이터로 기존 데이터와 일치하지 않는 (즉, 별도의 단계가 될 것이며, ) 삭제, 업데이트 및 삽입을 초래할 것입니다. 또한, 비교적 적은 필드 (15 중 최대 7 (20)의 출력 또는 제 2)로 변경된다.

    따라서 동시에 삽입 된 것입니다 함께 검색 될 가능성이와 기록은 물리적으로 서로 가까이 있어야한다. 때문에 그 접근 방식 이탈에 성능 손실을 만회하고 더 나은 그 개별 레코드 업데이트 모두의 실행 취소 / 재실행 비용보다합니까?

  16. from https://stackoverflow.com/questions/1271641/in-sql-is-update-always-faster-than-deleteinsert by cc-by-sa and MIT license