CS
  • CS-Study
  • database
    • B-Tree와 B+Tree
    • DB JOIN
    • DB Lock
    • DB 트래픽
    • DBCP (DB Connection Pool)
    • Flyway
    • Message Broker
    • MySQL InnoDB 스토리지 엔진
    • MySQL 엔진 아키텍처
    • RDB와 NoSQL
    • Redis
    • SQL Injection
    • 스키마 (Schema)
    • Table Scan과 Index Scan
    • Apache Kafka
    • Key
    • 뷰 (View)
    • 인덱스
    • 정규화
    • RDBMS, NoSQL의 클러스터링/리플리케이션 방식
    • 트랜잭션(Transaction)
    • 트랜잭션의 격리성(Transaction Isolation)
    • 프로시저와 트리거
    • DB 정규화 (Normalization)
  • etc
    • MSA
    • REST, REST API, RESTful
    • SOLID 원칙
    • TDD (Test-Driven Development)
    • 서버리스
    • 컨테이너와 도커
  • java
    • Collections
    • Garbage Collection
    • Generic
    • JDBC
    • Java Virtual Machine(JVM)
    • Java Thread
    • Java8 vs Java11 vs Java17
    • 객체지향 프로그래밍 OOP (Object Oriented Programing)
    • Optional
    • RxJava(Reactive Programming)
    • 문자열(String & StringBuffer & StringBuilder)
    • Synchronized
    • Virtual Thread
    • Wrapper Class
    • Equals()와 Hashcode()
    • final
    • Jackson 라이브러리
    • 리플렉션(Reflection)
    • static class와 static method
    • 스트림(Stream)과 람다(Lambda)
    • 스프링 프레임워크에서 사용되는 디자인 패턴
    • 예외처리(Exception)
    • Java Annotation
    • 추상클래스와 인터페이스
  • network
    • 3-way handshake
    • 4-way Handshake
    • DHCP(Dynamic Host Configuration Protocol)
    • DMZ(DeMilitarized Zone)
    • DNS(Domain Name System)
    • HTTP Method
    • HTTP 버전 비교
    • HTTP status code
    • HTTP
    • IP Address
    • Mutiplexing & Demultiplexing
    • OSI 7계층
    • SOP, CORS
    • TCP와 UDP
    • XSS와 CSRF
    • gRPC
    • Stateless와 Connectionless
    • 라우터 Router
    • 로드밸런서(Load Balancer)
    • 브라우저에 URL입력시 네트워크 상 일어나는 일
    • 서브넷 마스크, 게이트웨이
    • 웹 소켓과 소켓 통신
    • 쿠키(Cookie)와 세션(Session)
  • operating-system
    • IPC (Inter Process Communication)
    • 인터럽트
    • TLB
    • 스레싱 Thrashing
    • Thread Pool, Fork-Join
    • Thread Safe
    • 프로세스
    • 가상 메모리
    • 데드락 (DeadLock, 교착 상태)
    • 동기/비동기 & 블로킹/논블록킹
    • 동기화(Synchronization)
    • 메모리 할당과 단편화
    • 뮤텍스와 세마포어, 모니터
    • 세그먼테이션과 페이징
    • 운영체제
    • 캐시 메모리
    • Context switching(문맥 교환)
    • 컴파일
    • 파일 시스템
    • 페이지 교체 알고리즘(Page Replacement Algorithm)
    • 프로세서 스케줄링 알고리즘
    • 프로세스 주소 공간
  • spring
    • @Transactional
    • AOP(Aspect-Oriented Programming)
    • DTO, DAO, VO, Entity
    • DispatcherServlet
    • Hibernate, JPA, Spring Data JPA
    • Ioc와 DI
    • JPA 연관관계 맵핑
    • N+1 Problem
    • ORM
    • Persistence Context
    • SQL Mapper vs ORM vs QueryBuilder
    • Servlet Filter와 Spring Interceptor
    • Servlet
    • Spring MVC와 Spring Boot
    • Tomcat
    • WebFlux
Powered by GitBook
On this page
  • 테이블 전체 스캔(Table Full Scan)
  • 인덱스 스캔(Index Scan)
  • 인덱스 스캔(Index Scan) 종류
  • Index를 타지 않는 경우
  • 참고
  1. database

Table Scan과 Index Scan

Previous스키마 (Schema)NextApache Kafka

Last updated 10 months ago

테이블에 저장된 데이터를 읽는 방식은 Full Table Scan과 Index Scan 두 가지로 크게 나뉜다.

테이블 전체 스캔(Table Full Scan)

  • 개념

    • 테이블에 속한 블록 전체(모든 데이터)를 읽어서 데이터를 찾는 방법

    • 데이터베이스는 해당 테이블의 모든 레코드를 순차적으로 조회함

  • 사용 케이스

    • WHERE 절의 조건문을 기준으로 활용할 인덱스가 없는 경우

    • 전체 데이터 대비 대량의 데이터가 필요할 경우

    • 집계 함수 사용시(COUNT, SUM)

  • 특징

    • 인덱스 유무와 관계없이 항상 사용 가능함

    • 한 번의 I/O 요청으로 여러 블록을 한꺼번에 읽음

    • 테이블 대부분의 데이터를 찾을 때 유리함

    • 어떤 검색 조건을 사용하더라도 검색이 가능함

    • 대규모 테이블에서 비효율적

    • 조건에 맞는 데이터를 찾기 위해 모든 행을 검사해야 하므로 시간이 오래 걸림

인덱스 스캔(Index Scan)

  • 개념

    • 인덱스를 이용하여 데이터를 일정 부분 읽어서 ROWID로 테이블 레코드를 찾아가는 방법

      • ROWID: 테이블 레코드가 디스크 상에서 어디에 저장되었는지 가리키는 위치 정보

    • 인덱스를 구성하는 컬럼 값을 기반으로 데이터를 추출하는 기법

  • 사용 케이스

    • 인덱스는 데이터베이스 테이블에서 특정 열에 대한 정보를 가지고 있기 때문에 해당 열을 사용하여 검색할 경우 사용함

    • 고유한 값이나 범위 검색이 자주 필요한 경우

    • 자주 조회되는 컬럼에 대해 성능 최적화시

  • 특징

    • 절적한 인덱스가 있을 때만 사용 가능함

    • 대용량 데이터 중에서 극히 일부만 찾을 때 유리함

    • 인덱스를 유지 관리하기 위해 추가적인 리소스가 필요

인덱스 스캔(Index Scan) 종류

  • 인덱스 전체 스캔(Index Full Scan)

    • 테이블에 접근하지 않고, 인덱스 내의 열만을 참조하여 처음부터 끝까지 스캔하여 데이터에 접근하는 방식

    • 인덱스 크기가 작은 경우 빠른 검색 가능함

    • 테이블의 크기가 큰 경우 전체 테이블 스캔보다 느릴 수 있음

  • 인덱스 범위 스캔(Index Range Scan)

    • 인덱스의 일부 데이터만 읽어오는 방법으로, 인덱스의 범위를 지정하여 빠른 검색 가능

    • 특정 범위 내의 레코드만 읽기 때문에 비용이 적음

    • 검색 범위가 넓을 경우 느릴 수 있음

  • 인덱스 고유 스캔(Index Unique Scan)

    • 인덱스의 유일한 값을 검색하는 방법으로, 기본키나 고유 인덱스로 테이블에 접근함

    • 하나의 값만 읽기 때문에 비용이 가장 적음(인덱스 스캔 중 가장 효율적인 방식)

    • 인덱스 컬럼이 유일한 값을 가지고 있을 때만 사용 가능

  • 인덱스 루스 스캔(Index Loose Scan)

    • 인덱스에서 필요한 부분만 선택하여 스캔하는 방법으로, 인덱스의 범위를 지정하지 않고 검색을 수행함

    • 인덱스 범위 스캔과 비슷하게 특정 인덱스 범위만 스캔하지만, 중간에 필요없는 인덱스 키 값은 건너뛰고 검색함

  • 인덱스 병합 스캔(Index Merge Scan)

    • 여러 개의 인덱스를 병합하여 검색하는 방법

    • 복잡한 검색 조건을 처리할 수 있음

    • 인덱스의 크기가 작은 경우에만 유용하며, 인덱스 병합에 시간이 걸릴 수 있음

Index를 타지 않는 경우

인덱스를 타는 쿼리임에도 Table Full Scan 방식으로 동작하는 경우가 존재함

  1. 인덱스 컬럼의 변형

    SELECT * FROM users WHERE LOWER('name') = 'word' # 인덱스 사용불가
    SELECT * FROM table WHERE ages+10 = 30 # 인덱스 사용불가
    SELECT * FROM table WHERE ages = 20 + 10 # 인덱스 사용가능
    • 인덱스에 변형을 가하게 되면, DBMS가 인덱스를 이용하지 않음

  2. 인덱스 컬럼의 내부적인 데이터 형 변환

    select * from table where age = '30' # 인덱스 사용불가
    SELECT * FROM users where age = to_number('30') # 인덱스 사용가능
    • 정확한 데이터 타입을 넣어야 인덱스를 탈 수 있음

  3. 조건절에 NULL 또는 NOT NULL 사용

    SELECT * FROM users WHERE ages IS NULL # 인덱스 사용불가
    SELECT * FROM users WHERE ages IS NOT NULL # 인덱스 사용불가
  4. 부정형 NOT, LIKE, IN, OR 사용

    SELECT * FROM users WHERE ages != 31 # 인덱스 사용불가
    
    SELECT * FROM users WHERE first_name LIKE '%word%' # 인덱스 사용불가
    SELECT * FROM users WHERE first_name LIKE 'word%' # 인덱스 사용가능
    
    SELECT * FROM users WHERE ages IN (20, 21, 22)
    
    select * from table where name = 'word' or idx = 5
    • NOT의 경우, 일반적으로 NOT이 아닌 데이터 비율이 많기 때문에 인덱스를 타지 않음

    • LIKE의 경우, 사용할 때 전체 범위를 설정하면(%를 앞에도 사용하면) 타지 않음

    • IN의 경우, IN에 포함된 데이터의 비율이 매우 높아서 Table Full Scan을 하는 것이 낫다고 DB에서 판단하면 타지 않음

    • OR의 경우, DBMS가 최적의 OR 조거을 뽑기 힘들어서 Table Full Scan을 하는 경우가 많음

  5. 복합 인덱스의 순서를 정확하게 사용하지 않은 경우

    SELECT * FROM users WHERE name = 'hong' AND age = 30 # 인덱스 사용가능
    SELECT * FROM users WHERE age = 30 AND name = 'hong' # 인덱스 사용불가
    • 복합 인덱스의 순서가 name 다음 age라면, name -> age 순서로 조건을 걸어야 인덱스를 탈 수 있음


참고

테이블 스캔
인덱스를 차지 않고 풀스캔 하는 경우