9.2.4 GROUP BY 처리 ORDER BY 와 마찬가지로 스트리밍 처리가 불가능한 쿼리 중 하나. 인덱스를 사용하는 경우와 그렇지 않은 경우로 나뉜다. [1] 인덱스 스캔을 이용하는 GROUP BY(타이트 인덱스 스캔) 드라이빙 테이블에 속한 컬럼만으로 GROUP BY 를 할 때 그 컬럼에 이미 인덱스가 있다면 그 인덱스를 차례로 읽어서 그룹핑을 수행하고, 그 결과로 조인을 처리한다. 이미 정렬된 인덱스를 읽는 것이므로 쿼리 실행 시점에 추가적인 정렬 작업이나 임시테이블을 이용하지 않는다. 따라서 실행 계획의 Extra 칼럼에 별도의 내용이 없다. [2] 루스 인덱스 스캔을 이용하는 GROUP BY 루스 인덱스 스캔: 인덱스의 레코드를 건너뛰면서 필요한 부분만 읽는 방식 옵티마이저의 실행 계획 Ex..
9.2.3 ORDER BY 처리(Using filesort) (3) 정렬 처리 방법 ORDER BY 가 사용되면 아래 3가지 중 하나로 처리된다. 밑으로 갈수록 느리다. [1] 인덱스 사용 ORDER BY 에 사용된 컬럼 순서로 생성된 인덱스가 있어야한다. 인덱스를 순서대로 읽어서 결과 봔환. 즉, ORDER BY 가 사용되지 않아도 기본적으로 정렬되서 반환된다. 그렇다고 ORDER BY를 명시 하지 않는 것은 좋지 못한 선택이다. [2] 조인에서 드라이빙 테이블만 정렬 테이블을 조인한 후 정렬을 하게 된다면 레코드 건 수가 몇배가 늘어나고, 각각의 크기또한 늘어난 상태로 정렬을 하게 되기때문에 성능이 좋지 않다. 따라서 조인을 실행하기 전에 첫번째 테이블에 대해 정렬을 실행하고 그 다음 조인을 실행해야..
9.2 기본 데이터 처리 9.2.1 풀 테이블 스캔과 풀 인덱스 스캔 옵티마이저가 - 풀 테이블 스캔을 하는 조건: 테이블 레코드 건 수가 적어서 인덱스 읽는 것 보다 풀 테이블 스캔이 빠를 때(테이블이 한 페이지에 들어가는 경우), where 절이나 on 절에 적절한 인덱스가 없을 때, 인덱스 레인지 스캔을 했을 때 걸리는 레코드가 너무 많을 때. 새로운 페이지를 조회할 때 마다 디스크 I/O가 생기는데, innoDB의 경우 백그라운드 스레드가 한번에 4개, 8개, 64개까지 한번에 페이지를 버퍼 풀에 로드시킨다(리드 어헤드 기능). 시스템 변수 innodb_read_ahead_threshold로 리드 어헤드가 시작될 임계값을 조정 가능하다. 더 빨리 리드 어헤드 시키려면 낮추면 됨 풀 인덱스 스캔의 ..
같은 쿼리더라도 어떻게 동작할지는 매우 다양하다. 이런 선택지 중에서 최적인 방법을 경적하는 것이 옵티마이저이다. 9.1 개요 실행 계획을 이해하면 비효율적인 부분을 찾아서 더 최적의 계획을 수립할 수 있다. 이해해보자 (1) 쿼리 실행 절차 크게 3가지이다. 1. 요청된 SQL문을 parsing해서 SQL parse tree생성 2. parse tree를 확인하면서 어떤 테이블부터 읽고 어떤 인덱스를 이용할지 결정. 다음 내용을 처리한다. - 불필요한 조건 제거 및 복잡한 연산의 단순화 - 테이블 조인의 경우 어떤 테이블부터 읽을지 결정 - 각 테이블에 사용된 조건과 인덱스 통계 정보(?)를 이용해 사용할 인덱스 결정 - 가져온 레코드들을 임시 테이블에 저장하고 다시 한번 가공해야 하는지 결정 3. 결..
8.9 유니크 인덱스 인덱스라기보다 제약 조건. 8.9.1 유니크 인덱스와 일반 세컨더리 인덱스의 비교 읽기, 쓰기 성능의 관점에서 (1) 읽기 성능 차이 거의 없다. (유니크 인덱스는 1건만 읽어도 되니까.. 등등은 별 의미 없다. 인용-유니크하지 않은 세컨더리 인덱스에서 한 번 더 해야 하는 작업은 디스크 읽기가 아니라 CPU에서 컬럼값을 비교하는 작업) (2) 쓰기 중복체크를 하지 않아도 되기 때문에 일반적인 세컨더리 인덱스의 쓰기가 더 빠르다. MySQL에서는 유니크 인덱스의 중복 체크 과정에서 읽기 잠금, 쓰기 할 때는 쓰기 잠금을 거는데, 이 때 데드락이 빈번히 발생한다. (도대체 유니크 인덱스 왜쓰는 건가? 개 구데기네) 8.9.2 유니크 인덱스 사용 시 주의사항 요약: 정말 유일성을 보장해..
8.7 멀티 밸류 인덱스 MySQL 8.0 버전부터 JSON 관리 기능이 MongoDB에 비해 부족함이 없는 상태가 됨(배열 형태에 대한 인덱스 생성까지 지원) 다음 함수를 사용해야 옵티마이저가 인덱스를 활용한 실행계획을 세운다 - MEMBER OF() - JSON_CONTAINS() - JSON_OVERLAPS() 8.8 클러스터링 인덱스 비슷한 것들을 묶어서 저장하는 형태. InnoDB 스토리지 엔진에서만 지원 (1) 클러스터링 인덱스(=클러스터링 테이블) 테이블의 프라이머리 키에만 작용. 프라이머리 키 값이 비슷한 레코드끼리 묶어서 저장하는 것을 클러스터링 인덱스라고 한다. 프라이머리 키 값에 따라 레코드가 저장되는 위치가 결정된다. -> 프라이머리 키 값이 바뀌면 레코드의 저장 위치도 바뀐다. 즉..
8.5 전문 검색 인덱스 문서 내용 전체를 인덱스화해서 특정 키워드가 포함된 문서를 검색할 때는 일반적인 B-Tree사용 불가능 -> 구조적으로 동치, 범위 비교만 가능하다. 문서 전체의 검색에 대한 인덱스 알고리즘을 전문 검색(Full Text search) 인덱스라고 한다. 8.5.1 인덱스 알고리즘 인덱싱 기법에 따라 크게 어근 분석/n-gram 분석으로 나뉜다. - 어근 분석 알고리즘 document의 preprocessing으로 stop word 제거, stemming을 거쳐서 인덱싱 작업이 수행된다. stop word: 분석에 필요없는 단어(eg. ~이다, ~는 등 의미가 없는 형태소나 단어) stemming: 어근 분석이라 나오는데 형태소 분석. mecab을 플러그인 형태로 사용 가능. 일본..
클린 아키텍처를 읽었다. 읽고 있다. 앞으로도 계속 읽을 것이다. 현재 팀에서 도메인 주도 설계를 하고 있어서 입사하자 마자 읽은 책이 도메인 주도 설계 첫걸음, 클린 아키텍처였다. (물론 다 읽지는 않고 취사 선택해서 읽고 있다.) 개발자 커리어 시작 전에는 팀프로젝트에서 MVC패턴을 사용했는데, 이때 비즈니스 로직이라던지 인프라 라던지 레이어를 나눠서 할 생각은 하지도 못했다. 애초에 이런 설계법이 있는지 몰랐고.. 그 때는 예를 들어, 데이터베이스의 GET = 실제 비즈니스 모델에서 모델을 조회 이런 식으로 코드를 작성했었다. 실무에 와서 보니, 이렇게 코드를 작성하게 되면 비지니스 로직(abstraction)이 인프라(concretion)에 의존하게 되어 유지 보수에 좋지 못한 코드가 된다. (왜..
8.3.7. B-Tree 인덱스의 가용성, 효율성 인덱스 거는 순서가 중요하다..(또나오는 얘기..) 7.1 ~ 7.2 아래와 같은 쿼리 select * from table_temp where A='a' and B>=100; 를 실행한다. 이때 인덱스는 (A, B), (B, A)중 어떻게 걸어야하나 당연히 (A, B)로 걸어야한다. B의 정렬이 A에 의존하는 형태가 되어야 일단 A에 대한 동등 비교를 해서 레코드를 좀 털고 그다음에 B의 크기 비교 연산을 하는 편이 좋음. (B, A)로 걸면 일단 전체 레코드에서 B에 대해 크기 비교를 한 뒤 A에 대해 동등비교 해야하는데, A가 B에 의존해서 정렬되어도 정렬된 정보는 동등비교에서는 아무짝에 쓸모 없다. 그런데 또 select * from table_te..
5. 다중 칼럼 인덱스 여러 컬럼에 걸쳐서 인덱스를 거는 경우, n+1 번째 인덱스의 정렬은 n번째 인덱스 정렬에 의존한다. 즉, n+1번째 인덱스만 봤을 때, 키값은 일반적으로 정렬이 안 되어있다. -> 인덱스 거는 순서가 중요하다.(계속 언급되는 내용. 진짜 중요한 듯) 6. B-Tree 인덱스의 정렬 및 스캔 방향 1. 인덱스의 정렬 인덱스 정렬이란, B-Tree 리프노드들의 정렬관계를 말한다. 정방향으로 읽으면 오름차순, 역방향으로 읽으면 내림차순. 옵티마이저는 적절하게 정/역 어느 방향으로 읽어야할지 판단한다. 역방향으로 인덱스 읽는 경우가 정방향으로 읽을 때보다 느리다 - 인덱스 페이지 내의 레코드들은 항상 정방향으로 정렬되어있기 때문 - 페이지 잠금이 정방향 스캔에 유리한 구조이기 때문