728x90
Explain
Sql문 성능 개선에 빠질수 없는 것 들 중 하나인 Explain 쿼리를 한번 확인해 볼려고 한다.
컬럼 과 설명
id |
|
select_type | 쿼리의 유형을 나타냅니다. 주요 값은 다음과 같습니다:
|
table | 쿼리에서 접근하는 테이블의 이름입니다. |
partitions | 파티셔닝된 테이블을 사용하는 경우, 참조하는 파티션의 이름입니다. |
type | 테이블 접근 방법을 나타내며, 효율성을 나타냅니다. 효율적인 순서로는
|
possible_keys | 쿼리에서 사용할 수 있는 인덱스 목록입니다. |
key | 실제로 쿼리 실행 시 사용된 인덱스입니다. |
key_len | 사용된 인덱스의 길이입니다. 인덱스의 일부분만 사용하는 경우 이 값이 감소할 수 있습니다. |
ref | 인덱스의 어떤 열이 참조되는지를 나타냅니다. |
rows | MySQL이 예상하는 결과 행의 수입니다. 이 값이 클수록 성능 저하의 가능성이 있습니다. |
filtered | 쿼리에서 필터링된 행의 비율입니다. 이 값은 전체 행 수 중 필터링 후의 비율을 나타냅니다. |
Extra | 쿼리 실행에 대한 추가 정보를 제공합니다. 성능 순서로는
|
3. 실제 예제 분석
1. 기본 조회
EXPLAIN
SELECT *
FROM employees
WHERE department_id = 10;
결과는 다음과 같을 수 있습니다
id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | employees | range | department_idx | department_idx | 4 | NULL | 100 | 100.00 | Using where |
- type이 range로 나타나면 인덱스를 사용해 범위 검색을 수행함을 의미합니다.
- key가 department_idx로 표시되면 이 인덱스가 실제로 사용됨을 의미합니다.
- Extra에 Using where가 표시되면 WHERE 절에서 추가적인 필터링이 이루어짐을 의미합니다.
이 정보를 바탕으로 쿼리를 최적화하거나 인덱스를 조정하여 성능을 개선할 수 있습니다.
2. 인덱스가 없을 때 WHERE 절
EXPLAIN
SELECT *
FROM employees
WHERE department = 'Sales';
id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | employees | ALL | NULL | NULL | NULL | NULL | 5000 | 2.00 | Using where |
분석:
- type
- ALL — 인덱스가 없기 때문에 전체 테이블을 스캔합니다. 이는 비효율적일 수 있으며, 데이터 양이 많을 경우 성능 저하를 초래할 수 있습니다.
- key
- NULL — 인덱스가 사용되지 않음을 의미합니다.
- Extra
- Using where — WHERE 절을 사용하여 결과를 필터링합니다.
2. 4개 테이블을 조인할 때
EXPLAIN
SELECT e.name,
d.department_name,
p.project_name,
t.task_name
FROM employees e
JOIN departments d
ON e.department_id = d.id
JOIN projects p
ON e.project_id = p.id
JOIN tasks t ON p.task_id = t.id;
결과 예제
id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | e | ALL | department_idx | NULL | NULL | NULL | 5000 | 100.00 | |
1 | SIMPLE | d | eq_ref | PRIMARY | PRIMARY | 4 | e.department_id | 10 | 100.00 | |
1 | SIMPLE | p | eq_ref | PRIMARY | PRIMARY | 4 | e.project_id | 20 | 100.00 | |
1 | SIMPLE | t | eq_ref | PRIMARY | PRIMARY | 4 | p.task_id | 100 | 100.00 |
분석:
- type:
- ALL (employees) — employees 테이블을 전체 스캔합니다.
- eq_ref (departments, projects, tasks) — 인덱스를 사용하여 정확한 일치를 찾아 조회합니다. eq_ref는 인덱스를 통해 단일 행을 참조합니다.
- key:
- NULL (employees) — 인덱스가 사용되지 않음.
- PRIMARY (departments, projects, tasks) — 각 테이블의 기본 키가 사용됨.
- rows:
- 5000 (employees) — 전체 행 수.
- 10, 20, 100 — 조인된 테이블에서 각 단계별로 예측된 행 수.
- Extra: — 이 경우 특별한 추가 정보는 없음.
3. 서브쿼리를 사용했을 때
쿼리 예제:
EXPLAIN
SELECT name
FROM employees
WHERE department_id IN (SELECT id
FROM departments
WHERE location = 'New York');
결과 예제:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | PRIMARY | employees | ref | department_idx | department_idx | 4 | subquery | 1000 | 100.00 | Using where |
2 | SUBQUERY | departments | index | location_idx | location_idx | 4 | NULL | 10 | 100.00 | Using where |
분석:
- select_type:
- PRIMARY (outer query) — 외부 쿼리.
- SUBQUERY (inner query) — 서브쿼리.
- type:
- ref (employees) — 인덱스를 사용하여 결과를 참조합니다.
- index (departments) — 인덱스를 사용하여 전체 인덱스를 스캔합니다.
- key:
- department_idx (employees) — 인덱스가 사용됨.
- location_idx (departments) — 인덱스가 사용됨.
- rows:
- 1000 (employees) — 외부 쿼리에서 예측된 행 수.
- 10 (departments) — 서브쿼리에서 예측된 행 수.
- Extra:
- Using where — WHERE 절로 추가 필터링이 이루어짐.
728x90
'DB' 카테고리의 다른 글
[MySQL] Index 정리 (0) | 2024.12.12 |
---|---|
[MySql] 성능 개선에 관하여_해결 해 보자_2_경험 (0) | 2024.08.22 |
[MySql] 성능 개선에 관하여_고찰 (0) | 2024.08.06 |
[Redis] 성능과 가용성 (0) | 2024.03.26 |
[Redis] 확장성과 가용성을 위한 클러스터_뭔 말 인지 모르겠다. (0) | 2024.03.18 |