인덱스(Index)란
테이블의 특정 컬럼(또는 컬럼 조합)을 정렬된 구조(B-Tree 등)로 별도 저장해서
검색(WHERE), 정렬(ORDER BY), 조인(JOIN) 을 빠르게 만드는 자료구조다.
- 데이터(테이블) = 본문
- 인덱스 = 목차
목차가 없으면 책을 처음부터 끝까지 훑어야 한다(Full Table Scan).
SELECT * FROM customers WHERE email = 'user10@example.com';
SELECT * FROM orders ORDER BY ordered_at DESC LIMIT 20;
SELECT ...
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id;
SHOW INDEX FROM customers;
SHOW INDEX FROM products;
SHOW INDEX FROM orders;
SHOW INDEX FROM order_items;
SHOW INDEX FROM payments;
customers : PRIMARY(customer_id), UNIQUE(email)products : PRIMARY(product_id), UNIQUE(sku)orders : PRIMARY(order_id), INDEX idx_orders_customer_ordered(customer_id, ordered_at)order_items : INDEX idx_order_items_order(order_id), INDEX idx_order_items_product(product_id)payments : UNIQUE(order_id) (주문당 결제 1개)EXPLAIN
SELECT customer_id, name, status
FROM customers
WHERE email = 'user10@example.com';
key에 uk_customers_email이 잡히면 인덱스 사용type이 const 또는 ref면 매우 좋음rows가 작을수록 좋음EXPLAIN
SELECT order_id, ordered_at, total_amount
FROM orders
WHERE customer_id = 1
ORDER BY ordered_at DESC
LIMIT 10;
idx_orders_customer_ordered(customer_id, ordered_at)가 딱 맞는 이유복합 인덱스 (A, B)는 아래는 빠름:
WHERE A = ...WHERE A = ... AND B = ...WHERE A = ... ORDER BY B ...하지만 아래는 보통 못 씀(인덱스 효율 낮음):
WHERE B = ... 만
예: 현재 존재하는 인덱스
idx_orders_customer_ordered(customer_id, ordered_at)
예:
INSERT/UPDATE/DELETE 시:
따라서 인덱스를 무작정 많이 만들면:
EXPLAIN
SELECT product_id, name
FROM products
WHERE product_id=1;
type = const
key = PRIMARY
rows = 1
EXPLAIN
SELECT product_id, name
FROM products
WHERE name='USB-C Cable 1m';
type = ALL
key = NULL
rows = 30
EXPLAIN
SELECT *
FROM order_items
WHERE order_id = 1;
idx_order_items_order(order_id) 덕분에 빠름SELECT*
FROM orders o
JOIN order_items oi
ON o.order_id= oi.order_id
WHERE o.order_id=1;
order_items.idx_order_items_order(order_id)
WHERE order_id = 1
👉 JOIN 시:
EXPLAIN으로 실행계획 확인type=ALL)인덱스명: idx_payments_method_paidat
create index idx_payments_method_paidat
on payments(method, paid_at)
-- 확인 --
show index from payments;