MySQL에서`REPLACE`와`INSERT… ON DUPLICATE KEY UPDATE`의 실질적인 차이점은 무엇입니까?
내가 필요한 것은 특정 키를 사용하여 레코드의 모든 필드 값을 설정하는 것입니다 (키는 실제로 복합 임). 이러한 키가있는 레코드가 아직없는 경우 레코드를 삽입하는 것입니다.
REPLACE
작업을 수행하는 것처럼 보이지만 동시에 매뉴얼 페이지에서 INSERT ... ON DUPLICATE KEY UPDATE
.
그들 중 무엇을 더 잘 선택해야하며 그 이유는 무엇입니까?
REPLACE
내 마음에 떠오르는 유일한 "부작용"은 INSERT ... ON DUPLICATE KEY UPDATE
아마도 자동 증가 값을 증가시키는 것입니다 (다행히도 저는 사용하지 않습니다) . 염두에 두어야 할 다른 실질적인 차이점은 무엇입니까? 어떤 특정 경우 REPLACE
보다 선호 할 수 INSERT ... ON DUPLICATE KEY UPDATE
있습니까?
REPLACE
내부적으로 삭제를 수행 한 다음 삽입을 수행합니다. 해당 행을 가리키는 외래 키 제약 조건이있는 경우 이로 인해 문제가 발생할 수 있습니다. 이 상황에서는 REPLACE
실패하거나 더 나빠질 수 있습니다. 외래 키가 계단식 삭제로 설정되면 REPLACE
다른 테이블의 행이 삭제됩니다. 이는 REPLACE
작업 전후에 제약 조건이 충족 된 경우에도 발생할 수 있습니다 .
사용 INSERT ... ON DUPLICATE KEY UPDATE
하면이 문제 를 피할 수 있으므로 선호됩니다.
성능 측면에서 질문에 답하기 위해 두 가지 방법을 모두 사용하여 테스트를 수행했습니다.
: 속으로는 포함 교체
테이블에 1.Try 삽입을
1이 실패 2. 경우, 삭제 행과 새로운 행 삽입
중복 키 업데이트에 삽입 포함 :
테이블에 1.Try 삽입
한 실패 2.If, 업데이트 행
과 관련된 모든 단계가있는 경우 삽입, 성능 차이가 없어야합니다. 속도는 관련된 업데이트 수에 따라 달라집니다. 최악의 경우는 모든 문이 업데이트되는 경우입니다.
62,510 개 항목 (업데이트 만 해당)이 포함 된 InnoDB 테이블에서 두 문을 모두 시도했습니다.
캠핑 속도 : 다음으로 교체 : 77.411 초
중복 키 업데이트에 삽입 : 2.446 초
Insert on Duplicate Key update is almost 32 times faster.
테이블 크기 : Amazon m3.medium에서 12 개의 열이있는 1,249,250 행
REPLACE
대신을 사용할 INSERT ... ON DUPLICATE KEY UPDATE
때 주어진 키에 대해 여러 쿼리가 빠르게 도착할 때 키 잠금 또는 교착 상태 문제가 발생하는 경우가 있습니다. 후자의 원자 성은 (연쇄 삭제를 일으키지 않는 것 외에도) 그것을 사용하는 더 많은 이유입니다.
INSERT ... ON DUPLICATE KEY UPDATE보다 REPLACE를 선호하는 경우는 무엇이며 그 반대의 경우도 마찬가지입니까?
방금 FEDERATED 스토리지 엔진 INSERT...ON DUPLICATE KEY UPDATE
문이 있는 테이블의 경우 에는 허용되지만 실패 (오류 1022 : 쓸 수 없음, 테이블의 중복 키 ...)가 중복 키인 경우 실패 한다는 것을 알아 냈습니다 . 위반 발생 -MySQL 참조 매뉴얼 의이 페이지 에서 해당 글 머리 기호를 참조하십시오 .
다행히도 삽입 후 트리거 REPLACE
대신 INSERT...ON DUPLICATE KEY UPDATE
FEDERATED 테이블에 변경 사항을 복제하는 원하는 결과를 얻을 수있었습니다 .
Replace는 키가 이미 존재하는 경우 두 가지 작업을 수행하는 것처럼 보입니다. 아마도 그것은 둘 사이에 속도 차이가 있음을 의미합니까?
(INSERT) 하나의 업데이트 vs 하나의 삭제 + 하나의 삽입 (REPLACE)
편집 : 교체가 느릴 수 있다는 내 의미는 실제로 완전히 잘못되었습니다. 글쎄, 어쨌든이 블로그 게시물에 따르면 ... http://www.tokutek.com/2010/07/why-insert-on-duplicate-key-update-may-be-slow-by-incurring-disk-seeks /
모든 열을 나열하지 않으면 REPLACE
언급되지 않은 열을 대체 된 행의 기본값으로 재설정 할 것이라고 생각 합니다. ON DUPLICATE KEY UPDATE
언급되지 않은 열은 변경되지 않습니다.
"중복 키 오류의 경우 저장소 엔진이 삭제와 삽입이 아닌 업데이트로 REPLACE를 수행 할 수 있지만 의미는 동일합니다."
http://dev.mysql.com/doc/refman/5.7/en/replace.html
INSERT IGNORE가 데이터 변환에서 작동하지 않는 것처럼 보이기 때문에 때때로 REPLACE가 필요한 것 같습니다.
이렇게하면 가장 큰 도시 팝 자체 만 설정합니다.
INSERT IGNORE INTO largeCities (stateID, maximumCityPop, statePop) SELECT stateID, MAX (city.pop) as maximumCityPop, state.pop FROM city JOIN state on city.stateID = state.ID GROUP BY city.stateID ON DUPLICATE KEY UPDATE maximumCityPop = mostCityPop
이렇게하면 GROUP 함수를 부적절하게 사용하고 있습니다.
INSERT IGNORE INTO largestCities (stateID, largestCityPop, statePop) SELECT stateID, MAX(city.pop) as largestCityPop, state.pop FROM city JOIN state on city.stateID = state.ID GROUP BY city.stateID ON DUPLICATE KEY UPDATE largestCityPop = MAX(city.pop)
And if I do this, MySQL won't recognize the column name:
INSERT IGNORE INTO largestCities (stateID, largestCityPop, statePop) SELECT stateID, MAX(city.pop) as largestCityPop, state.pop FROM city JOIN state on city.stateID = state.ID GROUP BY city.stateID ON DUPLICATE KEY UPDATE largestCityPop = city.largestCityPop
This works, but seems just plain ugly:
INSERT IGNORE INTO largestCities (stateID, largestCityPop, statePop) SELECT * FROM (SELECT stateID, MAX(city.pop) as biggestCityPop, state.pop FROM city JOIN state on city.stateID = state.ID GROUP BY city.stateID) x ON DUPLICATE KEY UPDATE largestCityPop = biggestCityPop
'Program Tip' 카테고리의 다른 글
Python의 파일에서 한 번에 한 문자를 읽는 방법은 무엇입니까? (0) | 2020.11.13 |
---|---|
IF a == true OR b == true 문 (0) | 2020.11.13 |
OpenCV에서 Watershed의 마커를 정의하는 방법은 무엇입니까? (0) | 2020.11.13 |
Git 병합은 기본 병합 메시지를 사용하지 않고 기본 메시지로 편집기를 엽니 다. (0) | 2020.11.13 |
Git을 사용할 때 Visual Studio에서 분기 (로컬 / 원격)를 어떻게 새로 고치나요? (0) | 2020.11.13 |