카테고리 없음

디비 스터디 5주차

JIN_Coder 2023. 7. 3. 02:57

INSERT

INSERT 문장이 동시에 실행되는 경우 INSERT 문장 자체보다는 테이블의 구조가 서능에 더큰 영향을 미침

INSERT와 SELECT의 성능을 동시에 빠르게 만들 수 있는 테이블 구조는 없음(타협해야함)

 

 

고급옵션

INSERT IGNORE

INSERT ON DUPLICATE KEY UPDATE

유니크 인덱스나 프라이머리 키에 대해 중복 레코드를 어떻게 처리할지를 결정함

 

 

INSERT IGNORE

유니크 인데스나 프라이머리 키가 중복으로 존재하는 경우, 레코드의 칼럼과 테이블의 칼럼이 서로 호환이 되지 않는 경우 모두 무시하고 다음 레코드를 처리 할 수 있게 해줌

여러 레코드를 하나의 INSERT 문장으로 처리하는 경우 유용함

salaries 테이블의 프라이머리 키 : emp_no, from_date
중복 레코드가 있으면 에러 발생
하지만, IGNORE 옵션이 있다면 에러를 경고로 바꾸고 INSERT 진행함(무시함)

 

중복 데이터 뿐만아니라, 테이터 타입이 일치 하지 않을 경우 칼럼의 기본값이 들어감

함부로 쓰다간 의도치 않은 에러도 무시하고 INSERT 하기 때문에 주의해야함

 

 

INSERT ON DUPLICATE KEY UPDATE

IGNORE은 무시하고 인서트를 진행했지만, ON DUPLICATE KEY UPDATE는 중복이 발생하면 UPDATE 문장의 역할을 수행함

daily_statistic의 프라이머리 키 : target_date, stat_name

특정 날짜의 stat_name이 최초 저장되는 경우엔 INSERT 문이 실행되고, ON DUPLICATE KEY UPDATE 이하의 절은 실행안됨

이미 레코드가 존재한다면, ON DUPLICATE KEY UPDATE 이하의 절이 실행됨

 

 

LOAD DATA 명령 주의 사항

LOAD DATA : RDBMS에서 데이터를 빠르게 적재 할 수 있는 방법

MYSQL엔진과 스토리지 엔진의 호출횟수를 최소화 하고, 스토리지 엔진이 직접 데이터를 적재하기 때문에 일반적인 INSERT문보다 빠름

 

단점

단일 스레드로 실행 - 적재할 데이터 파일이 크다면 시간이 오래걸림

단일 트랜잭션으로 실행 - 언두 로그가 삭제되지 못하고 유지되어야 함(레코드를 찾는데 많은 오버헤드 발생)

 

LOAD DATA 문장으로 데이터 파일을 하나 말고 여러개로 준비해서 실행하는것이 좋음

테이블 복사 작업이라면, LOAD DATA보다 INSERT SELECT 를 사용해서 필요 데이터를 INSERT하는것이 좋음

 

 

성능을 위한 테이블 구조

INSERT의 성능은 쿼리 문장 보다 테이블의 구조에 의해 결정됨

 

 

대량 INSERT 성능

INSERT될 레코드들을 프라이머리 키 값 기준으로 미리 정렬해서 INSERT 문장을 구성하는것이 성능에 도움이 될 수 있음

프라이머리 키로 정렬된 경우 시간이 반으로 줄어듦

 

정렬이 안되면 랜덤 프라이머리 키 값을 B-tree 방식으로 메모리를 읽어서 INSERT 하기 때문에 오래걸림

 

테이블의 세컨더리 인덱스는 SELECT 문의 성능은 높히지만, INSERT 문의 성능은 떨어짐

백그라운드 작업의 부하를 유발하기 때문에 세컨더리 인덱스를 남용하면 성능상 안좋음

 

 

프라이머리 키 선정

InnoDB 스토리지 엔진을 사용하는 테이블의 프라이머리 키는 클러스터링 키인데,

이는 세컨더리 인덱스를 이용하는 쿼리보다 프라이머리 키를 이용하는 쿼리의 성능이 훨씬 빨라지는 효과를 냄

프라이머리 키는 INSERT, SELECT 성능에 대립되기 때문에 두가지 모두 만족하는 경우는 드물다고 함

 

SELECT는 거의 안하고 INSERT가 많은 테이블은 프라이머리 키를 단조증가,감소하는 패턴으로 설계함(주로 로그)

인덱스로 줄여주면 좋음

 

반대의 경우 인덱스를 걸어서 SELECT 잘되게 해도 큰 영향은 없음

 

 

*소량의 테이블 구조 및 쿼리에 투자 할 시간에 대용량(메인) 테이블 구조 및 쿼리에 시간을 쓰는게 현명함