type에 대해서 자세히 알아보자. 성능 최적화에 있어서 이 값의 의미를 파악하는 게 굉장히 중요하다. 
ALL : 풀 테이블 스캔
DROP TABLE IF EXISTS users; # 기존 테이블 삭제 CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), age INT );
INSERT INTO users (name, age) VALUES ('Alice', 30), ('Bob', 23), ('Charlie', 35);
EXPLAIN SELECT * FROM users WHERE age = 23; # type : ALL
users 테이블의 데이터는 age를 기준으로 정렬되어 있지 않고 id를 기준으로 정렬되어 있다. 그래서 age = 23의 값을 가진 데이터를 찾으려면 테이블의 처음부터 끝까지 다 뒤져봐야 한다. 그래서 실행 계획의 type이 ALL로 나온 것이다. index : 풀 인덱스 스캔
DROP TABLE IF EXISTS users; # 기존 테이블 삭제 CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), age INT );
-- 높은 재귀(반복) 횟수를 허용하도록 설정 -- (아래에서 생성할 더미 데이터의 개수와 맞춰서 작성하면 된다.) SET SESSION cte_max_recursion_depth = 1000000; -- 더미 데이터 삽입 쿼리 INSERT INTO users (name, age) WITH RECURSIVE cte (n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 1000000 -- 생성하고 싶은 더미 데이터의 개수 ) SELECT CONCAT('User', LPAD(n, 7, '0')), -- 'User' 다음에 7자리 숫자로 구성된 이름 생성 FLOOR(1 + RAND() * 1000) AS age -- 1부터 1000 사이의 난수로 나이 생성 FROM cte;
CREATE INDEX idx_name ON users (name);
EXPLAIN SELECT * FROM users ORDER BY name LIMIT 10;

type: index인걸로 봐서 풀 인덱스 스캔을 했다. 즉, 인덱스를 처음부터 끝까지 다 읽어서 필요한 데이터를 뽑아냈다.
name을 기준으로 정렬해서 데이터를 가져와야 하기 때문에, name을 기준으로 정렬되어 있는 인덱스를 조회한다.
(덩치가 큰 users 테이블의 데이터를 하나씩 찾아보면서 정리를 하는 것보다, 이미 name을 기준으로 정렬되어 있는 인덱스를 참고하는 게 효율적이라고 판단한 것이다.)users 테이블에서 조회한다.