인덱스란?
- 인덱스는 테이블안의 데이터를 더 빠르게 찾기 위해 사용하는 자료구조이다.
- 특정 컬럼을 기준으로 정렬된 별도의 자료구조를 만들어서, WHERE 조건이나 검색 같은 쿼리를 훨씬 빠르게 만든다.
- 적용 대상은 테이블의 특정 컬럼이며 자주 사용되는 컬럼에 적용되면 좋다.
- 인덱스를 만들어도, 평소처럼 쿼리 날리면 된다. DB가 내부적으로 인덱스를 자동으로 활용해서 Full table scan이 아니라 인덱스를 따라서 빠르게 찾아간다.
- 인덱스를 사용 못하는 경우
- LIKE “%abc” : 앞에 와일드카드 붙은 경우
- WHERE LOWER(email) = ‘abc’ : 함수를 감싸면 인덱스를 못 쓴다.
- OR 여러 개 묶인 복잡한 WHERE 절
⇒ 이런 경우에는 인덱스 무시하고 그냥 Full table scan 쓸 수도 있음 그래서 EXPLAIN으로 실제 인덱스를 쓰는지 확인해야함.
⇒ type이 Using index면 인덱스를 활용하는 거고, type = ALL이면 full table scan이다.
EXPLAIN SELECT * FROM users WHERE email = 'abc@gmail.com';
⇒ Mysql 8부터는 실행시간까지 포함된 상세 분석 결과 출력 가능하다.
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'abc@gmail.com';
- 장점 : 쿼리 성능 대폭 향상, 데이터가 많아질수록 효과가 좋다.
- 단점 : 인덱스를 많이 만들면, INSERT, DELETE, UPDATE 성능이 낮아진다. 또한 인덱스도 저장공간을 차지한다.
뷰란?
- 복잡한 쿼리를 단순하게 만들고, 재사용성과 가독성을 높이기 위한 도@ㄷ
- SELECT 쿼리를 마치 테이블처럼 가상화 한 것을 의미한다.
CREATE VIEW active_users AS
SELECT id, name FROM users WHERE status = 'ACTIVE';
⇒ 이렇게 하면 이젠 select * from users; 만 쳐도 된다.
- 적용 대상은 여러 테이블을 JOIN 한 경우거나, WHERE이나 GROUP BY가 복잡한 쿼리를 자주 쓰는 경우이다.
- 뷰는 INSERT, UPDATE 안된다. 읽기 전용이다. 컬럼 변경하고 싶으면 뷰를 재생성한다.
- 장점: 코드 재사용성이 높고, 가독성이 좋고 보안에도 유용하다.
- 보안에 유용한 이유는: 민감한 정보 노출이 제한된다.
- 단점: 뷰 자체는 성능 향상 도구가 아니다. 또한 뷰 안의 쿼리가 복잡하면, 또 성능 저하된다.
인덱스 VS 뷰
- 데이터 검색 속도 개선이 목적이면 → 인덱스
- 복잡한 쿼리 깔끔하게 쓰려면 → 뷰
- 자주 조회하는 조건이 있으면 → 인덱스, 뷰
- INSERT, UPDATE가 많은 테이블 → 인덱스 쓰면 안되고, 뷰는 상관 없다. (영향 거의 없음)
인덱스는 SQL에서 직접 생성해야한다.
CREATE INDEX idx_user_email ON users(email);
- DB 구조에 영향을 주는 것이기 때문에, Spring 코드에서는 할 수 없다.
- DDL은 스프링 코드에서 할 수 없음
- JPA에서는 @Table 어노테이션에서 인덱스 지정 가능하다. 이건 Hibernate가 스키마를 자동 생성할 때 반영된다.
@Table(
name = "users"
indexs = @Index(name = "idx_user_email", columnList = "email")
)
뷰도 기본적으로 SQL에서 생성해야한다.
CREATE VIEW user_summary AS
SELECT id, name, created_at FROM users WHERE statuss = "ACTIVE";
- DB 구조에 영향을 주는 것이기 때문에, Spring 코드에서는 할 수 없다.
- DDL은 스프링 코드에서 할 수 없음
- JPA에서는 @Table 어노테이션에서 인덱스 지정 가능하다. 이건 Hibernate가 스키마를 자동 생성할 때 반영된다.
@Entity
@Table(name = "user_summary")
public class UserSummary {
private Long id,
private String name,
private LocalDateTime createdAt;
}
'프로젝트 정리' 카테고리의 다른 글
WebDriverWait vs pageLoadTimeout (0) | 2025.01.27 |
---|---|
OOM SCORE 점수란? (0) | 2025.01.11 |
스프링 시큐리티 JWT 기반 인증 흐름 정리 (0) | 2024.12.27 |
Docker 볼륨과 EBS 볼륨 차이 (0) | 2024.12.21 |
깃허브 액션과 슬랙 연동해서 배포 결과 알림 받기 (0) | 2024.12.20 |