Open danbi5228 opened 1 year ago
EXPLAIN SELECT 1
, EXPLAIN SELECT 1 FROM DUAL
SHOW PROCESSLIST; // 이걸로 쿼리 실행 중인 프로세스 id 확인
// 실제 커넥션 id(프로세스 번호)가 8인 커넥션에서 실행하고 있는 쿼리의 실행 계획 살펴보기
EXPLAIN FOR CONNECTION 8;
해당 명령은 옵티마이저가 의도된 인덱스를 사용하지 못해서 풀 스캔을 한다거나 잘못된 실행 계획을 선택한 것이 아닌지 확인할 때 유용하게 사용할 수 있는 명령이다
이 명령을 사용했을 때 Plan is not ready yet
메시지가 표시될 때는
해당 커넥션에서 아직 쿼리의 실행 계획을 수립하지 못한 상태에서 EXPLAIN FOR CONNECTION 명령이 실행된 것을 의미한다
실행 계획을 수립할 여유 시간을 좀 더 주고, 다시 명령을 실행하면 된다
두 개의 테이블을 조인하는 쿼리에서 조인 조건에 상수가 없고 둘다 변수(e1.emp_no, e2.emp_no)인 경우
옵티마이저는 e1 테이블을 먼저 읽고 조인을 위해 e2을 읽을 때 인덱스 레인지 스캔과 풀 테이블 스캔 중에서 어느 것이 효율적일지 판단할 수 없다
EXPLAIN
SELECT *
FROM employees e1, employees e2
WHERE e2.emp_no >= e1.emp_no;
만약 사번이 1~1억 까지 있다고 가정하면 e1.emp_no=1 인 경우에는 e2 테이블을 1억 건 전부를 읽어야 하고, e1이 1억이면 e2 테이블을 한 건만 읽으면 된다
즉, e1 테이블의 emp_no가 작을 때는 e2 테이블을 풀 테이블 스캔, e1테이블의 emp_no가 큰 값이면 e2 테이블을 인덱스 레인지 스캔으로 접근하는 형태를 수행하는 것이 최적의 조인 방법이다
이를 줄여서 표현하면 레코드마다 인덱스 레인지 스캔을 체크한다 라고 할 수 있다
이 것이 Extra 칼럼에 표시되는 Range checked for each record의 의미이다
Extra 칼럼을 자세히보면 (index map: 0x1)은 사용할지 말지를 판단하는 후보 인덱스의 순번을 나타내고 16진수로 표시된다.
0x1은 이진수로 1이고 의미는 e2 테이블의 첫 번째 인덱스를 사용할지 아니면 테이블을 풀 스캔할지를 매 레코드 단위로 결정하면서 처리된다
SHOW CREATE TABLE employees
명령으로 테이블의 구조를 조회했을 때 제일 먼저 출력되는 인덱스를 의미type이 ALL로 표시되어 있는데 index map에 표시된 후보 인덱스를 사용할지 여부를 검토하고 도움이 되지 않아 최종적으로 풀 테이블 스캔을 사용하기 때문에 ALL로 표시된 것
469p에서 index map: 0x19 -> 이진수로 11001 이고 표에서 1인 값에 해당하는 인덱스 pk, gender, phone를 사용 가능한 인덱스 후보로 선정했음을 의미한다
각 레코드 단위로 이 후보 인덱스 가운데 어떤 인덱스를 사용할지 결정하게 되나, 실제로 어떤 인덱스가 사용됐는지 알 수 없다.
8.0 버전부터 CTE(Common Table Expression)을 이용해 재귀 쿼리를 작성할 수 있게 됐다
WITH RECURSIVE cte (n) AS
(
SELECT 1
UNION ALL
SELECT n + 1 FROM cte WHERE < 5
)
SELECT * FROM cte;
WITH 구문을 이용한 CTE가 사용 됐다고 해서 꼭 recursive로 표시되지는 않는다
WITH 구문이 재귀 CTE로 사용될 경우만 표시
다음 스터디
2022-11-15 pm 10:20
학습 범위
정리 범위