From edd0845ce968b2c415a0da0d2c9564630b87c382 Mon Sep 17 00:00:00 2001 From: "SEOPSS\\prero" Date: Tue, 16 May 2023 21:58:20 +0900 Subject: [PATCH 1/2] index --- ...04\355\202\244\355\205\215\354\262\230.md" | 96 +++++++++++++++++++ ...04\355\202\244\355\205\215\354\263\220.md" | 5 + ...0\352\263\274 \354\236\240\352\270\210.md" | 43 +++++++++ .../\354\235\270\353\215\261\354\212\244.md" | 84 ++++++++++++++++ 4 files changed, 228 insertions(+) create mode 100644 "JangseopLee/4. \354\225\204\355\202\244\355\205\215\354\262\230/4.3 MyISAM \354\212\244\355\206\240\353\246\254\354\247\200 \354\227\224\354\247\204 \354\225\204\355\202\244\355\205\215\354\263\220.md" create mode 100644 "JangseopLee/5. \355\212\270\353\240\214\354\240\235\354\205\230\352\263\274 \354\236\240\352\270\210/5.1-4 \355\212\270\353\236\234\354\236\255\354\205\230\352\263\274 \354\236\240\352\270\210.md" create mode 100644 "JangseopLee/8. \354\235\270\353\215\261\354\212\244/\354\235\270\353\215\261\354\212\244.md" diff --git "a/JangseopLee/4. \354\225\204\355\202\244\355\205\215\354\262\230/4.2 InnoDB \354\212\244\355\206\240\353\246\254\354\247\200 \354\227\224\354\247\204 \354\225\204\355\202\244\355\205\215\354\262\230.md" "b/JangseopLee/4. \354\225\204\355\202\244\355\205\215\354\262\230/4.2 InnoDB \354\212\244\355\206\240\353\246\254\354\247\200 \354\227\224\354\247\204 \354\225\204\355\202\244\355\205\215\354\262\230.md" index e330e5c..4256cbf 100644 --- "a/JangseopLee/4. \354\225\204\355\202\244\355\205\215\354\262\230/4.2 InnoDB \354\212\244\355\206\240\353\246\254\354\247\200 \354\227\224\354\247\204 \354\225\204\355\202\244\355\205\215\354\262\230.md" +++ "b/JangseopLee/4. \354\225\204\355\202\244\355\205\215\354\262\230/4.2 InnoDB \354\212\244\355\206\240\353\246\254\354\247\200 \354\227\224\354\247\204 \354\225\204\355\202\244\355\205\215\354\262\230.md" @@ -155,3 +155,99 @@ SERIALIZABLE 가장 높은 격리수준으로, Phantom Read 문제도 발생하지 않습니다. 하지만, 다른 격리수준보다 더 많은 Locking(잠금)이 필요하므로 성능이 떨어질 수 있습니다. 이 중에서도 일반적으로는 REPEATABLE READ를 사용하는 것이 권장됩니다. 하지만, 특정 상황에 따라 다른 격리수준을 사용해야 할 수도 있습니다. + +------------ till 2023.03.18 ----------------------------- + +> Duble write buffer +> about undo log +> about change buffer +> about redo log +> adaptive_hash_index +> storage enginge diff + +## 쓰기를 보장하는 Double Write Buffer + + - redo log : 변경된 것만 기록 -> 그럼 변경(더티페이지를 디스크로 플러시) 중에 일부는 실패하면? + - 일부 실패한 변경 내역 : 파셜페이지, 톤 페이지 라고 불리며 이를 막기 위해 '더블라이팅' 기능 사용 + > 버퍼풀의 더티페이지에 a,b,c 기록 -> double write 버퍼에 기록 -> 성공하면 dw 버퍼는 삭제, 실패하면 사용 + - innodb_boublewrite + - 순차 쓰기를 하는 hdd에서는 부담이 없지만 순차나 랜덤io나 비슷한 sdd 에선 고려 필요 <-> 데이터 무결성 높힘 + - 서버 성능을 위해 리두로그 동기화를 off 했다면 dw buffer도 off 추천 -> 리두로그 동기화도 안켜고 켜는건 의미 없음 + +## 트렌젝션을 위해 언두로그 + + ### 언두로그란 + - DML 변경 전 이전 undo 한 버전을 저장한 로그 + > 트렌젝션 보장 : 롤백시 사용된다! + > 격리수준 보장 : 변경 중인 데이터에 조회가 걸릴때 사용 될 수 있다! (격리수준에 따라 다름) + + ### 언두로그 모니터링법 + > 언두로그가 너무 커진다 + - 5.5 이전 버전의 언두로그 공간은 줄지 않아서 100G 테이블을 삭제해도 언두로그에 그 크기의 테이블이 복제되는 셈 + - 트렌젝션이 여러개 동시 일어날때 처음의 트렌젝션이 종료되지 않으면, 그 사이에 커밋된 트렌젝션들도 결국 언두로그를 들고 있어야 한다. + - 다행이 5.7 이후에는 알아서 공간 정리해준다 + +```mysql +SHOW ENGINE INNODB STATUS \G +SLELECT count FROM ino~~ --8.0 버전에서 쓸수 있는 명령어로 서버별로 언두로그 건수를 조회 할 수 있다. +--또한 u,d 명령어는 mvcc와 복구 모두에 쓰이지만 i는 롤백에만 쓰기 때문에 언두로그 갯수에 치지 않는다 +``` + + ### 언두로그의 테이블스페이스 + - 5.6 버전 이전엔 언두로그는 모두 시스템 테이블스페이스에 저장 ibdata.ibd + > 문제는 시스템 테이블스페이스의 언두로그는 mysql 서버 초기화될때 생성되서 확장의 한계. + > innodb_undo_tablespaces > 2 로 설정하면 별도의 로그 파일 사용 ( 8.0 부터는 강제 ) + - undo tablespace truncate -> 필요없어진 언두로그 테이블 스페이스 운영체계에 반납, 8버전부터이며 + 자동모드는 undo thread가 undo purge 작업을 통해 커밋되어 필요 없어진 언두로그 공간을 반납한다 + 수동모드는 명령어로 한번 언두퍼지작업을 하는 셈. 했으면 재 활성화 필요. + ??아니 아깐 테이블스페이스에 저장 안한다며 8.0부터 -> 시스템 테이블 스페이스랑 언두테이블스페이는 다른듯 + +## 인덱스 업데이트를 위한 체인지 버퍼 + + > 레코드 변경에는 인덱스 업데이트도 필요 -> 인덱스 업데이트에는 랜덤한 디스크 리딩이 필요해 비용 높음 + > 버퍼 풀에 인덱스 페이지가 있으면 업데이트 + > 버퍼 풀에 없다면 임시 메모리공간(체인지버퍼) 에 저장했다가 업데이트 (단, 유니크인덱스는 중복체크가 필요해 불가능) + > 체인지 버퍼의 내역은 백그라운드 스레드(체인지 버퍼 머지 스레드)가 병합 + > 5.5 이전엔 인서트만 이런식으로 사용되서 인서트 버퍼라고도 불림 + > innodb_change_buffering 에 변수에 따라, 추가 삭제 업데이트 중 뭘 버퍼링 걸건지 정할 수 있음 + > 체인지 버퍼는 insert, update가 너무 빈번하면 사이즈를 늘릴 수 있으며 기본적으론 버퍼풀의 25~50% + +## 영속성 듀러블을 위해 리두로그와 로그 버퍼 + + > 비정상 종료등의 상황에서 미처 기록되지 못한 아이들을 가지고 있다. + > 모든 DBMS는 쓰기보다 읽기를 고려하고 있어, 파일 쓰기는 디스크 랜덤 엑세스가 필요하며 이에 쓰기 비용이 낮은 자료구조인 리두 로그로 먼저 기록한다. + > 리두로그는 1. 커밋되었지만 기록되지 않은 데이터. 2. 롤백되었지만 이미 기록된 데이터 들을 위해 존재한다. + > 1.은 리두로그 내역을 기록하면 되고, 2는 리두로그로 상황을 파악하고 언두로그로 원복시킨다. + +```mysql +innodb_flush_log_at_trx_commit = 0 -- `약 1초에 한번 리두를 디스크로 동기화 하는 주기를 가진다. 최대 1초까지는 트랜젝션은 커밋은 했지만 디스크에는 아직 안올리고 리두에만 있다가 비정상 종료되면 디스크에는 없을 수 있다. ?? 아니 리두로그내역도 사라지는겨?? 아니면 리두로그가 있으니 복구 될 수 있나? += 1 --매 커밋마다 리두는 디스크로 올린다. 때문에 변경한 데이터는 사라진다 - 이건 언두로그의 데이터 아닌겨? += 2 --매 커밋마다 디스크로 적지만 동기화는 1초마다, 따라서 mysql 서버는 죽고 운영체제가 살아있으면 트렌젝션 데이터는 살아있다.?? 뭔말이야 이짐 적었다며 +``` + + > 8버전부터 리두로그 끌 수 있으며 대용량 데이터 적재등에서 적재시간 단축이 가능하다. + > 단 재 활성화를 안해준다면, 비정상 종료 후에 재시작 되면 서버마다 다른 데이터 시점을 가지게 된다. 따라서 비활보다는 일부 손실이 있어도 된다면 시스템 변수를 0이나 2로 해서 쓰자 + +## 버퍼 풀에 빠르게 접근하는 어댑티브 해시 인덱스 + + > 일반적인 인덱스는 테이블에 사용자가 세팅해둔 b-tree 를 의미한다. + > 어댑티브 해시 인덱스는 innodb 스토리지가 사용자가 자주 쓰는 데이터에 대한 자동 생성한 인덱스로, 끄고 킬 수 있다. + > b-tree는 빠르다 불릴 수 있지만, 엄청나게 많은 요청에 대해서는 부족 할 수 있다. 이에 맞게 자주 읽히는 데이이터 페이지 키 값으로 해시 인덱스를 만들고 즉시 찾아가는 방식을 가진다. -> 리프노드까지 찾아가지 않고 바로 찾아가는! -> 내부잠금(세마포어) 경합도 획기적으로 준다! + > b-tree 인덱스 고유 번호와 실제 키값의 조합 + > 8.0부터는 어댑티브 해시 인덱스의 파티션 기능 제공 + > 다음과 같은 경우 이득 : + 1. 디스크 읽기가 많지 않은, 디스크데이터 크기 = 버퍼풀 크기 + 2. 동등 조건 =, in 검색이 많은 경우 + 3. 쿼리가 데이터 중 일부에만 집중되는경우 + ???왜 + > 다음에서 손해 : + 1. 디스크 읽기가 많은 경우 + 2. 조인이나 like 많은 경우 + 3. 매우 큰 데이터를 가진 테이블의 데이터 폭이 넓게 읽는 경우 + > 요점은 버퍼 풀 내에서 빠른접근을 더 빠르게 해준 다는 것 + > 단, 사용하게 되면 이 인덱스부터 찾느라 효용이 없어도 찾을 거란 것 + > 단, 테이블 변경 및 삭제에도 어댑티프 해시 인덱스가 걸려있으면 다 제거하고 처리해야 해서 비용이 많이 든다는 것. + +## 스토리지 엔진간 비교 간단히 + +'8.0 부터는 innodb 가 짱임' diff --git "a/JangseopLee/4. \354\225\204\355\202\244\355\205\215\354\262\230/4.3 MyISAM \354\212\244\355\206\240\353\246\254\354\247\200 \354\227\224\354\247\204 \354\225\204\355\202\244\355\205\215\354\263\220.md" "b/JangseopLee/4. \354\225\204\355\202\244\355\205\215\354\262\230/4.3 MyISAM \354\212\244\355\206\240\353\246\254\354\247\200 \354\227\224\354\247\204 \354\225\204\355\202\244\355\205\215\354\263\220.md" new file mode 100644 index 0000000..2c08445 --- /dev/null +++ "b/JangseopLee/4. \354\225\204\355\202\244\355\205\215\354\262\230/4.3 MyISAM \354\212\244\355\206\240\353\246\254\354\247\200 \354\227\224\354\247\204 \354\225\204\355\202\244\355\205\215\354\263\220.md" @@ -0,0 +1,5 @@ + +## 키 캐시 +## 운영체제의 캐시 및 버퍼 +## 데이터 파일과 프라이머리 키 구조 + diff --git "a/JangseopLee/5. \355\212\270\353\240\214\354\240\235\354\205\230\352\263\274 \354\236\240\352\270\210/5.1-4 \355\212\270\353\236\234\354\236\255\354\205\230\352\263\274 \354\236\240\352\270\210.md" "b/JangseopLee/5. \355\212\270\353\240\214\354\240\235\354\205\230\352\263\274 \354\236\240\352\270\210/5.1-4 \355\212\270\353\236\234\354\236\255\354\205\230\352\263\274 \354\236\240\352\270\210.md" new file mode 100644 index 0000000..7365acf --- /dev/null +++ "b/JangseopLee/5. \355\212\270\353\240\214\354\240\235\354\205\230\352\263\274 \354\236\240\352\270\210/5.1-4 \355\212\270\353\236\234\354\236\255\354\205\230\352\263\274 \354\236\240\352\270\210.md" @@ -0,0 +1,43 @@ +> 5.1 트랜젝션 +> 5.2 MySQL엔진 잠금 / +> 5.3 InnoDB 스토리지 엔진 잠금 +> 5.4 격리 수준 + +## 트렌잭션 + +- 잠금은 동시성(여러군데서 변경하면 예측 불가!), 트랜젝션은 정합성(원하는 값)을 보장한다 +- 트렌젝션을 지원하는 InnoDB, 안하는 MYIsam +- 트렌젝션이 지원되지 않는다면 쿼리 작업의 중간 실패에 대한 조건 처리를 모두 분기해야 할 수도 있다! + +- 트렌젝션은 최소한의 범위를 가지는 것이 좋다 -> 여러 트렌젝션으로 쪼개기, 외부통신은 트랜젝션으로 잡지 않기, 불필요한 시점에서 잡지 않기 + +## 5.2 MySQL 엔진 잠금 + +- `글로벌락` : mysql 서버 전반에 걸쳐 db, table 이 달라도 영향 받는다. 여러 데이터베이스에 존재하는 MyIsam이나 Memory 테이블에 대해 덤프(백업) 만들때 사용한다. InnoDB 에서 백업시에 글로벌락이 걸려도 변경 허용하며 백업을 잠시 멈추는 방식으로 바뀌었다 +- `테이블락` : 명시적 묵시적으로 테이블을 잠구는 것으로, 쿼리 실행시에 작동되나, InnoDB의 경우 레코드 잠금을 제공해서 스키마 변경시에만 잠구곤 한다. +- `네임드락` : 클라인언트간의 상호 동기화를 위해 처리하며, 문자열에 대해 잠금을 진행한다. 자주 쓰이진 않지만, 복잡한 요건으로 레코드 변경시에 데드락을 줄이는 방향으로 사용 될 수 있다. +- `메타데이터락` : 명시적으로 쓰이진 않으며 테이블의 이름들 등을 바꿀때 원본과 대상을 모두 잠구는 방식으로 일어난다. 운영중인 테이블의 변경시에 InnoDB 트랜젝션과 동시 사용하여 최근데이터를 저장하는 방식으로 변경하는 방식도 있다. + +## InnoDB 스토리지 엔진 잠금 + + - 스토리지 자체 레코드 기반 잠금방식을 탑재 -> 높은 동시성 처리 + - 레코드와 레코드 사이의 간격을 잠그는 갭락 + - 레코드락 : 인덱스의 레코드를 잠그는 방식 *** + - 갭락 : 레코드사이에 새로운 레코드 생성을 제어하는 것, 넥스트 키 락의 일부로 주로 사용 + - 넥스트 키락 : 레코드락 + 갭락 -> 바이너리 로그에 기록된 커리가 레플리카 서버에서 실행될때 소스 서버에서 만들ㅇ 낸 결과와 동일하게 만들기 위함 + - 자동 증가락 : autoincrement 속성있는 컬럼테이블 동시 insert 시 테이블 수준의 락이 필요, 5.1 부터 값에 따라 변경가능한데, 0 -모든 insert문장 자동증가락, 1- insert 건수를 예측가능하다면 더 빠른 래치(뮤텍스)를 이용해 처리, 2- 무조건 경량 래치(뮤텍스) 사용한다. 연속된 자동증가값을 보장하진 않으며 인터리빙 모드라고 지칭한다. 동시 처리 능력이 좋아지나, 유니크 값만 보장하고 값이 달라질 수 있다. + +-`인덱스와 잠금` : InnoDB는 레코드가 아닌 인덱스를 잠구는 방식으로 인덱스가 없다면 전체 테이블, 혹은 과도한 범위를 잠굴 수 있다. -`레코드 수준의 잠금의 문제` : 테이블 잠금은 쉽게 발견, 해결 될 수 있으나, 자주 사용되지 않는 레코드라면 잘 발견되지 않는다. + +## 5.4 격리수준 + +- read uncommitted, read committed(오라클), repeatable read(MySQL), serializable (격리정도가 높아지며, 동시처리성이 떨어진다. 단 seariable수준이 아니면 성능 차이는 거의 없다.) +- R unc : Drity read, non-repeatable read, phantom read +- R com : non-r, ph +- Rp re : ph(inno는 제외) +- serial : 해당사항 없음 + +- `RUC` : 커밋안한것도 읽는 방식, 더티 리드, 즉 작업이 완료 되지 않은 변경값도 다른 트랜젝션에서 사용하는 것으로, 격리수준으로 인정 받지 못하기도하는 정합성 문제가 많은 격리수준. +- `RC` : 변경 후 커밋되지않았다면, 언두 여역에서 데이터를 가져온다. 다만, repeatable read 즉 동일 트렌젝션 내 반복적인 리드에도 같은 결과값을 가져오지 못하는 문제가 발생한다. 타 트랜젝션에서 값을 커밋하는 것에 따라 달라지기 때문. (입금 총 합에 대한 쿼리를 돌린다고 할때 매번 달라지는 문제가 발생 할 수 있다.) +- `RR` : InnoDB 기본 상태로 바이너리 로그를 가진 mysql 서버에서는 이 수준 이상이 필요. 롤백을 위해 언두로그에 백업하고 실제값을 변경한다 이러한 구조를 MVCC 라고 한다. 리드 커밋티드와의 차이는 언두 영역에 백업된 레코드ㅈ중 어떤 영역을 읽는 가 이다. 트랜젝션 번호보다 작은 값으로 읽는데, 다시말해 내가 트랜젝션 시작하고나서 누가 바꾼건 무시한단 말이다. 또한 정합성 문제가 발생할 수 있는데, 조건에 맞는 값을 다른 트랜젝션에서 추가했을 경우등에 해당한다. 이러한 현상을 PHANTOM READ 라고 한다. +- `SR` : 가장 단순하고 엄격한 격리수준으로 동시처리성이 떨어진다. 읽기 작업조차 락을 걸게된다. 단 이노디비에서는 팬톤 리드가 갭락과 넥스트 키락 덕분에 일어나지 않으므로 굳이 이 수준까지 사용 할 필요는 없다. diff --git "a/JangseopLee/8. \354\235\270\353\215\261\354\212\244/\354\235\270\353\215\261\354\212\244.md" "b/JangseopLee/8. \354\235\270\353\215\261\354\212\244/\354\235\270\353\215\261\354\212\244.md" new file mode 100644 index 0000000..9aef620 --- /dev/null +++ "b/JangseopLee/8. \354\235\270\353\215\261\354\212\244/\354\235\270\353\215\261\354\212\244.md" @@ -0,0 +1,84 @@ +> 8.1 디스크 읽기 방식 +> 8.2 인덱스란 +> 8.3 B- tree 인덱스 (다중컬럼인덱스) + +- 인덱스의 성능은 옵티마이저의 발전에도 불구하고 관리자의 역할로서, 쿼리 튜닝에 중요한 부분이다. + +## 8.1 디스크 읽기 방식 + +- 성능 튜닝과 직접적인 디스크 io +- 랜덤io(hdd sdd 비슷)와 순차io(hdd에서 sdd에 비해 느림) + +- `랜덤io` 디스크에 기록하기 위해 각각의 페이지만큼 시스템 콜 요청이 필요하며, +- hdd에서는 매 io마다 디스크헤더의 움직이 필요하다. sdd에서도 전체 throughput이 떨어지는 편 +- 주로 인덱스 레인지 스캔에 해당. + +- `순차io`에서도 빈번한 동기화 작업은 랜덤io만큼 성능 저하를 일으키며, 이에 기업용들은 RAID컨트롤러의 캐시등으로 효율적 처리한다. +- 큰 테이블의 데부분을 읽을 경우 풀 테이블 스캔-순차IO를 사용하여 빨리 많은 레코드를 읽는다. + +- `쿼리성능개선`은 결국 `랜덤IO`를 줄이는 것이며, 다시말해, `처리에 필요한 데이터`만 읽도록 하는 것이다. + +## 8.2 인덱스 + +- 인덱스는 레코드 주소 - 키 의 쌍으로 빠른 탐색을 가능케 하며, 정렬이 중요하다. + +### 자료구조적 분류 + +- SortedList : 인덱스, 항상 정렬 유지, 저장시(i,u,d)마다 높은 비용, 빠른 탐색(select) -> 인덱스를 추가한다는 건 저장속도를 감수한다는 것/ 과한 인덱스는 저장용량도 영향 +- ArrayList : 데이터 파일, 저장순서 유지 + +- 인덱스 : pk - 레코드를 식별할 대표 칼럼, not null, no dup / sk - 세컨더리 인덱스, pk비슷 대체제 + +### 알고리즘적 분류 + +- `B-Tree 인덱스` : 오래되고 발전된 기법, 칼럼 변경 없이 인덱싱, 위치기반으로 발전된게 R-Tree\ +- balanced, 인덱스는 정렬된 상태, 일반적 용도 +- 리프 노드 - 데이터 레코드 주소/ 루트, 브렌지 노드 - 자식노드 주소 (이때 데이터 자체는 비정렬적, innoDB는 클러스터링-데이터파일 내부에 비트리가 있는 셈, 때문에 MyISAM은 sk가 물리적주소를 InnoDB는 sk가 논리주소를 가진다, 각각의 장단점이 있다) +- Hash 인덱스 : 칼럼 값으로 해시값 계산해 인덱식, 빠른 검색, but 값 변경 방식으로 전방일치 등 `값의 일부 검색`이나 `범위 검색`에서는 사용 불가, 메모리기반DB에서 많이 사용 + +- unique 조건은 옵티마이저에게는 1개 이상을 찾아야 할지 말지에 대한 중요한 문제 + ㅡ + +### 인덱스의 추가삭제 + +- B-Tree 구조에서 새로운 인덱스 키가 추가될때, 리프노드가 꽉 차있다면 리프노드의 split이 이뤄져야 하며, 이때 상위 브랜치 노드까지 처리범위가 늘어난다. +- 일반적으로 쓰기 비용이 1이면 인덱스당 1.5 비용이 추가된다. +- InnoDB의 경우 인덱스추가 작업을 지연 할 수 있지만 유니크 칼럼은 아니다. + +- InnoDB는 삭제 마킹 후 후 처리하지만, 다른 스토리지 엔진같은 경우 체인지버퍼같은 기능이 없어서 인덱스키 삭제후 쿼리가 돌아간다.(변경은 삭제와 추가의 합) + +- B-Tree 인덱스의 검색은 전체 일치, 앞부분 일치에서만 사용가능하다. 또 연산을 통한(변형된) 정렬이나 검색은 장점을 이용 할 수 없다. +- 특히 이노디비에서는 검색한 인덱스를 잠궈서 레코드를 잠궈, 인덱스가 적절히 없다면 전체를 잠궈버릴 수 도 있다. + +### 비트리 인덱스 사용에 미치는 요소 + +- 페이지(이노디비 스토리지엔진이 디스크에 저장하는 최소단위)는 읽쓰의 최소단위이자, 버퍼링 최소단위이다. 따라서 인덱스도 노드 구분이 페이지 단위이다. +- 인덱스 페이지는 보통 16kb로 16\*1024 / 16(키값 예시크기)+12(자식노드주소예시크기) = 585개 저장 가능하다. -> 이는 쿼리가 레코드 500개를 읽을때마다 디스크 읽기가 발생한다는것. +- 인덱스 키가 커지면 전체적 인덱스 키가 커지고, 인노디비 버퍼풀이나 마이아이삼 키캐시 영역은 한정적이 캐시가능한 레코드 수는 줄어버린다. + +- 기수성, 선택도, selectivity, cardinality : 인덱스 키 값 가운데 유니크한 값의 수 -> 중복이 없을 수록 선택도가 높고, 검색이 빨라진다 +- 선택도가 낮아도 정렬과 그루핑 작업으로 개선 시킬수도 있다. 인덱스는 항상 검색만을 위한 것이 아니기 때문. +- `유니크 값` ???? + +- 인덱스를 이용해 테이블을 읽은건, 그냥 읽는 것에 비해 비용이 높다. -> 일반적 옵티마이저에서는 직접 1건보다 4.5배 비용이 높게 인덱스 통한 읽기를 예측한다. -> 전체의 20% 넘은 내용을 읽으면 인덱스로 읽기는 손해. -> 따라서 힌트를 추가해도 의미 없다. + +### 비트리 인덱스로 데이터 읽기 + +`인덱스 레인지 스캔` + +- 다른 것보다 빠른 방식으로, 읽어야하는 범위 결정시 사용. 하지만 이 방식도 데이터 파일에 읽어야하는 갯수만큼 io를 필요하므로 20% 이상 읽어야 할땐 랜덤io보다 직접읽기로 순차io가 나은셈. + `인덱스 풀 스캔` +- 인텍스의 처음부터 끝까지를 모두 읽는 방식. 데이터 레코드를 모두 읽는거보단 사이즈가 작은 인덱스를 모두 읽는게 저렴 -> 인덱스 명시된 칼럼만으로 처리가 가능할때. 인덱스 레인지보다 느리고 테이블 풀 스캔보단 빠르다. + `루스 인덱스 스캔` +- 인덱스 레인지,풀 스캔이 타이트 스캔이며 이에 반대되는 개념 +- 레인지 스캔과 비슷하게 작동 되나 중간 중간 스킵, +- group by, max min 에 최적화 하는 경우 사용 + `인덱스 스킵 스캔` +- 루스 인덱스 스캔과 비슷한 방식으로 그룹함수만 사용 되던 것들이 WHERE 조건절 검색에도 사용 되는 확장성을 가진 것이다. +- 루스 인덱스 스캔과 동일하게 인덱스에 무슨 값이 있는지 확인하고, 필요 없는 것들을 스킵하고 넘어가는 방식! + +### 다중 칼럼 인덱스 + +- 일반적 테이블에서는 다중 칼럼을 사용하며, 인덱스의 두번째 칼럼은 첫번째 칼럼에 의존해 정렬된다. 세번째는 두번째에 의존 하는 방식, 따러서 칼럼의 위치가 중요하다. + +--end 230509 From e635b55479457f2d27ec5438594490c67f44edbf Mon Sep 17 00:00:00 2001 From: "SEOPSS\\prero" Date: Tue, 16 May 2023 22:06:51 +0900 Subject: [PATCH 2/2] index contents merge --- .../\354\235\270\353\215\261\354\212\244.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/JangseopLee/8. \354\235\270\353\215\261\354\212\244/\354\235\270\353\215\261\354\212\244.md" "b/JangseopLee/8. \354\235\270\353\215\261\354\212\244/\354\235\270\353\215\261\354\212\244.md" index 9aef620..1b7338a 100644 --- "a/JangseopLee/8. \354\235\270\353\215\261\354\212\244/\354\235\270\353\215\261\354\212\244.md" +++ "b/JangseopLee/8. \354\235\270\353\215\261\354\212\244/\354\235\270\353\215\261\354\212\244.md" @@ -39,7 +39,7 @@ - unique 조건은 옵티마이저에게는 1개 이상을 찾아야 할지 말지에 대한 중요한 문제 ㅡ -### 인덱스의 추가삭제 +### 인덱스의 추가 삭제 - B-Tree 구조에서 새로운 인덱스 키가 추가될때, 리프노드가 꽉 차있다면 리프노드의 split이 이뤄져야 하며, 이때 상위 브랜치 노드까지 처리범위가 늘어난다. - 일반적으로 쓰기 비용이 1이면 인덱스당 1.5 비용이 추가된다.