Join 시 여러 테이블에 접근해야 하는데, 이때 접근하는 우선순위를 정합니다.
Driving TB (
== Outer TB): 먼저 접근하는 TB
Driven TB (== Inner TB): Driving TB 접근 이후 접근하는 TB
ex) Driving TB: 학생, Driven TB: 비상연락망
SELECT 학생.학번, 학생.이름
비상연락망.관계, 비상연락망.연락처
FROM 학생
JOIN 비상연락망
ON 학생.학번 = 비상연락망.학번
WHERE 학생.학번 IN (1, 100);
MySQL에서 실행계획을 보면 nested loop join 이 많이 보입니다.
업무에 바로 쓰는 SQL 튜닝(1) 에서 설명한 것과 같이 MySQL은 nested loop join을 주로 사용하기 때문입니다.
Nested Loop Join이란, Driving TB 데이터 1건 당 Driven TB을 반복해서 조회하는 것 입니다
ex)
위의 sql을 실행하면 몇 번 데이터에 접근할까요?
100)1000)100)1000)하지만, 보통의 TB에는 자주 사용되는 조건에 대해 index를 걸기 때문에 index를 건다면 데이터 접근 횟수가 줄어들 것 입니다.
회사에서 SQL 튜닝 요청할 때, 혹은 쿼리 성능을 파악하면서 아래의 용어들을 많이 사용하고 듣습니다.
인덱스를 타지 않고 테이블에서 바로 데이터를 훑는 방식입니다
-> 당연히 모든 데이터를 읽어야 하니 성능 측면에서 좋지 않습니다
인덱스를 처음부터 끝까지 수행하는 방식입니다
-> 하지만 이것도 검색 범위를 줄여야 함
인덱스를 범위 기준으로 스캔한 뒤, 결과를 바탕으로 테이블을 찾아가는 방식입니다
BETWEEN+AND 구문이거나, <, >, LIKE 구문 등 비교연산 및 구문에 포함될 때 인덱스 범위 스캔 수행기본키, 고유인덱스로 테이블에 접근하는 방식입니다
eq(=) 조건으로 작성-> 스캔 방식 중 가장 효율적인 스캔 방법
물리적으로 인접한 page를 차례로 읽는 순차 접근 방식입니다
물리적으로 떨어진 page들에 임의로 접근하는 임의 접근 방식입니다
where 조건문 기준으로 데이터가 저장된 디스크에 접근하게 됩니다
맨 처음 disk에서 검색하는 조건. SQL 튜닝에서 가장 중요한 핵심 사항입니다
ex)
SELECT *
FROM TAB
WHERE ID = 1 -- ID에 인덱스가 걸려있음
AND CODE = 'A';
ID = 1 조건: 액세스 조건 -> 일부 데이터에 접근하게 된다만약 CODE = 'A'를 액세스 조건으로 선택했다면, 많은 양의 데이터에 접근해야 한다
disk에서 가져온 데이터에서 추가로 추출하거나 가공하는 연산하는 조건입니다
ID = 1 조건으로 가져온 데이터에서 `CODE = 'A' 로 필터링 한다열의 where 조건절에 따라 선택되는 데이터 비율
선택도 = 선택한 데이터 건수 / 전체 데이터 건수
하나의 데이터 유형으로 정의되는 데이터 행의 갯수
카디널리티 = 전체 데이터 건수 * 선택도
ex) 주민등록번호: 카디널리티 높음 / 이름: 카디널리티 중간 / 성별: 카디널리티 낮음
데이터베이스가 데이터를 빨리 찾을 수 있게 추가 정보를 전달하는 것
ex) USE INDEX
SELECT 학번, 전공코드
FROM 학생 /*! USE INDEX (학생_IDX01) */
WHERE 이름 = '유재석';
SELECT 학번, 전공코드
FROM 학생 USE INDEX (학생_IDX01)
WHERE 이름 = '유재석';
-> 학생_IDX01 인덱스 를 사용해서 데이터를 찾아주세요
학생_IDX01 인덱스가 삭제된다면 오류 메세지가 출력된다 (오라클의 경우엔 무시됨)