cprayer
Nov 24, 2025 - 2 min read

CREATE INDEX ... DESC를 써도 실제 저장은 ASC였고 8.x부터는 실제로 DESC 인덱스를 만들 수 있다관련 링크:
(A, B, C) 복합 인덱스는 leftmost prefix 규칙으로 (A)와 (A, B)를 포함WHERE A=? AND B=? 또는 ORDER BY A, B 같은 쿼리는 별도 인덱스 없이 커버된다WHERE B=?처럼 where 조건을 주는 경우에는 `(A, B, C) 인덱스를 사용 불가능하니 별도로 인덱스를 만들어야 한다EXPLAIN과 EXPLAIN ANALYZE로 쿼리 플랜을 보거나 쿼리 플랜 대비 실제 쿼리 실행 결과 비교EXPLAIN FORMAT=TREE
SELECT first_name, last_name, SUM(amount) AS total
FROM staff INNER JOIN payment
ON staff.staff_id = payment.staff_id
AND
payment_date LIKE '2005-08%'
GROUP BY first_name, last_name;
-> Table scan on <temporary>
-> Aggregate using temporary table
-> Nested loop inner join (cost=1757.30 rows=1787)
-> Table scan on staff (cost=3.20 rows=2)
-> Filter: (payment.payment_date like '2005-08%') (cost=117.43 rows=894)
-> Index lookup on payment using idx_fk_staff_id (staff_id=staff.staff_id) (cost=117.43 rows=8043)EXPLAIN 명령을 통해 어떤 쿼리 플랜이 적용되는지 확인 할 수 있다EXPLAIN ANALYZE
SELECT first_name, last_name, SUM(amount) AS total
FROM staff INNER JOIN payment
ON staff.staff_id = payment.staff_id
AND
payment_date LIKE '2005-08%'
GROUP BY first_name, last_name;
-> Table scan on <temporary> (actual time=0.001..0.001 rows=2 loops=1)
-> Aggregate using temporary table (actual time=58.104..58.104 rows=2 loops=1)
-> Nested loop inner join (cost=1757.30 rows=1787) (actual time=0.816..46.135 rows=5687 loops=1)
-> Table scan on staff (cost=3.20 rows=2) (actual time=0.047..0.051 rows=2 loops=1)
-> Filter: (payment.payment_date like '2005-08%') (cost=117.43 rows=894) (actual time=0.464..22.767 rows=2844 loops=2)
-> Index lookup on payment using idx_fk_staff_id (staff_id=staff.staff_id) (cost=117.43 rows=8043) (actual time=0.450..19.988 rows=8024 loops=2)EXPLAIN ANALYZE는 쿼리를 실제 실행하여 예상 시간과 실제 시간을 비교할 수 있다(8.x부터)관련 링크:
INDEX HINT 사용하여 쿼리 플랜 대신 지정한 인덱스를 사용 / 무시SELECT
O.order_id, O.customer_id
FROM
orders O
FORCE INDEX (pk_orders) -- pk_orders 인덱스를 반드시 사용하도록 강제
WHERE
O.order_date > DATE_SUB(NOW(), INTERVAL 7 DAY);FORCE INDEX, IGNORE INDEX, USE INDEX 등의 문구를 사용하여 인덱스를 강제로 사용하게 하거나 무시, 혹은 사용을 유도할 수 있다QueryHint Annotation, Querydsl의 경우 forceIndex / useIndex 메소드 등을 통해 인덱스 힌트를 줄 수 있다관련 링크:
Y/N나 상태 코드 같이 cardinality가 낮은 컬럼은 인덱스에 넣는 것이 오히려 더 성능에 안 좋을 수 있다