TIL 230916

geon·2023년 9월 16일
0

CSAPP (p.591 ~ 598)

5.12.2 Store Performance

Subtle Issues - write/read dependency

메모리 읽기가 최근 메모리 쓰기에 의존하는 경우 성능이 떨어짐
load unit은 메모리 읽기 시 store unitstore buffer를 확인하고, 주소가 일치하는 엔트리가 존재하면 retrieve해서 load operation의 결과로 사용

5.13 Performance Improvement Techniques

성능 최적화를 위한 기초 전략

  • High-Level Design
    적합한 알고리즘, 자료구조 사용

  • Basic coding principles
    optimization blocker 피하기
    과도한(중복된) 함수 호출을 제거 (연산을 루프 밖으로 꺼내기, 효율성을 위해 modularity와의 타협을 선택적으로 수용)
    필요 없는 메모리 참조 제거

  • Low-level optimizations
    하드웨어의 능력을 최대한 끌어내기 위해 코드 구조화
    loop unrolling, ILP를 높이기 위한 방법(multiple accumulators, reassociation 등), conditional data transfer를 가능하게 하기 위해 조건 연산을 functional style로 작성

Real MySQL 1권 (p.265 ~ 280)

인덱스

함수 기반 인덱스

  • 가상 칼럼을 이용한 인덱스
  • 함수를 이용한 인덱스

멀티 밸류 인덱스

하나의 데이터 레코드가 여러 개의 키 값을 가질 수 있는 형태의 인덱스
JSON 배열 타입 필드에 저장된 원소들에 대한 인덱스
MEMBER OF, JSON_CONTAINS, JSON_OVERLAPS와 같은 함수를 이용해서 검색해야 인덱스를 활용 가능

클러스터링 인덱스

InnoDB 스토리지 엔진에만 존재
프라이머리 키 값에 의해 레코드의 저장 위치가 결정됨, 즉 프라이머리 키 값이 변경되면 해당 레코드의 물리적인 저장 위치가 바뀜

클러스터링 키 선택 우선순위
프라이머리 키 -> NOT NULL 옵션의 유니크 인덱스 중 첫 번째 인덱스 -> 내부적으로 생성한 대체 키

MyISAM 테이블의 경우 데이터 레코드가 INSERT될 때 데이터 파일의 끝 또는 임의의 빈 공간에 저장되고, 한 번 저장된 위치는 절대 바뀌지 않음, 레코드가 저장된 주소(ROWID)는 MySQL 내부적으로 레코드를 식별하는 아이디로 인식됨
MyISAM 테이블의 인덱스는 ROWID를 사용해서 실제 데이터 레코드를 찾음

InnoDB 테이블의 세컨더리 인덱스는 해당 레코드가 저장된 주소가 아닌 프라이머리 키를 저장하고, 인덱스 검색 시 프라이머리 키 값 확인 후 다시 검색해서 최종 레코드를 찾음

장점

프라이머리 키로 검색할 때 처리 성능 매우 빠름 (특히 범위 검색)
테이블의 모든 세컨더리 인덱스가 프라이머리 키를 가지고 있으므로 커버링 인덱스로 처리할 수 있는 경우가 많아짐

단점

클러스터링 키 값의 크기가 큰 경우 세컨더리 인덱스 크기도 커짐
세컨더리 인덱스를 통해 검색하는 경우 프라이머리 키로 다시 한 번 검색해야 하므로 처리 속도가 느림
INSERT 시 프라이머리 키에 의해 레코드 저장 위치가 결정되므로 처리 속도가 느림
프라이머리 키 변경 시 레코드를 DELETE하고 INSERT하는 작업이 필요하므로 처리 속도가 느림

결국 장점은 빠른 읽기, 단점은 느린 쓰기인데, OLTP에서는 쓰기 읽기 비율이 2:8 ~ 1:9이므로 느린 쓰기 감수 가능

유니크 인덱스

유니크 인덱스와 일반 세컨더리 인덱스는 구조상 아무런 차이가 없음
읽기 성능 차이는 미미함
쓰기 성능은 유니크 인덱스가 떨어짐 (중복 체크 과정이 필요, InnoDB의 경우 체인지 버퍼를 사용해서 인덱스 쓰기를 미루는데, 유니크 인덱스는 중복 체크를 바로 해야 하므로 작업 버퍼링이 불가능함)

외래키

InnoDB 스토리지 엔진에서만 생성 가능
외래키 제약이 설정되면 자동으로 인덱스 생성

잠금 확장

자식 테이블 레코드의 외래키 칼럼이 변경되는 경우 부모 테이블 해당 레코드에 읽기 잠금을 걸어야 함 (해당 참조키가 존재하는지 체크)
ON DELETE CASCADE 조건이 걸려 있는 경우 부모 테이블 레코드 삭제 시 연관된 자식 테이블 레코드 쓰기 잠금이 필요

profile
뭐라도 적기

0개의 댓글