전체 글

전체 글

    [MySQL] OFFSET 100000 지연 원인과 복합 키셋 페이징 전환 방법

    OFFSET 페이징: 실무적 정의와 운영상 중요성MySQL에서 OFFSET 페이징은 정렬된 결과의 앞부분을 건너뛴 뒤 지정한 행 수만 반환하는 방식이다. LIMIT 20 OFFSET 100000은 100001번째 행으로 즉시 이동하는 명령이 아니다. MySQL은 정렬 순서에 맞는 선행 100000행을 확인하고 버린 뒤 다음 20행을 반환해야 한다.인덱스를 사용하더라도 건너뛸 행을 탐색하는 비용은 사라지지 않는다. 페이지가 뒤로 갈수록 스캔하는 인덱스 레코드와 CPU 사용량이 증가하며, 필요한 컬럼을 인덱스가 포함하지 않으면 테이블 접근까지 반복될 수 있다. 동시 요청이 집중되는 운영 환경에서는 버퍼 풀 경쟁과 디스크 I/O 병목으로 이어진다.OFFSET 100000 이후의 목록 조회는 마지막 행의 정렬 ..

    [MSSQL] Sort 메모리 부족과 TempDB Spill 진단: Memory Grant 문제 구분 방법

    Sort 연산자: 실무적 정의와 운영상 중요성MSSQL에서 Sort 연산자는 입력 행을 ORDER BY, GROUP BY, DISTINCT, 윈도 함수 또는 조인 처리에 필요한 순서로 재배열한다. 정렬 대상이 메모리 안에 들어오면 작업은 메모리에서 끝나지만, 확보한 작업 공간보다 데이터가 커지면 일부 정렬 데이터를 TempDB에 기록한다. 이 현상이 TempDB Spill이다.Spill 여부와 Memory Grant 부족은 같은 의미가 아니다. Spill은 실제 실행 중 메모리가 부족했다는 결과이고, Memory Grant 문제는 왜 부족해졌는지를 설명하는 원인이다. DBA는 실제 실행 계획의 Sort 경고를 먼저 확인한 뒤 메모리 요청량, 실제 부여량, 최대 사용량, 카디널리티 오차를 순서대로 대조해야..

    [MySQL] ORDER BY와 LIMIT의 filesort를 제거하는 정렬 인덱스 설계

    ORDER BY와 LIMIT: 실무적 정의와 운영상 중요성MySQL에서 ORDER BY와 LIMIT는 정렬된 결과 중 일부 행만 반환하는 목록 조회의 핵심 구문이다. 관리 화면, 게시물 목록, 주문 이력처럼 최신 데이터 몇 건을 조회하는 기능에서 반복적으로 사용된다.대량 테이블에서 가장 중요한 판단 기준은 정렬 결과를 만든 뒤 LIMIT을 적용하는지, 정렬된 인덱스를 읽다가 필요한 행 수에서 중단하는지이다. 전자는 실행 계획의 Extra에 Using filesort가 나타날 수 있으며, 후보 행이 많으면 CPU 사용량과 메모리 소비, 임시 파일 I/O를 유발한다. 후자는 적절한 복합 인덱스를 순서대로 읽으므로 정렬 작업 자체를 생략할 수 있다.필터·정렬 컬럼의 기본 순서는 명확하다. WHERE절의 동등 ..

    [MSSQL] AUTO_UPDATE_STATISTICS 임계값과 대량 적재 후 오래된 통계 진단

    AUTO_UPDATE_STATISTICS: 실무적 정의와 운영상 중요성SQL Server의 AUTO_UPDATE_STATISTICS는 데이터 변경량을 추적하고, 옵티마이저가 오래되었다고 판단한 통계를 쿼리 컴파일 과정에서 갱신하는 데이터베이스 옵션이다. INSERT, UPDATE, DELETE, MERGE로 데이터 분포가 변하면 수정 횟수가 누적되지만, 변경 직후 모든 통계가 즉시 갱신되는 구조는 아니다.자동 갱신 여부는 통계별 수정 카운터와 임계값으로 결정된다. 임계값을 넘은 통계도 해당 통계를 참조하는 쿼리가 컴파일되거나 캐시된 실행 계획을 실행하기 전까지 실제 갱신이 지연될 수 있다. 따라서 대량 적재가 끝났다는 사실만으로 통계가 이미 최신 상태라고 판단하면 안 된다.오래된 통계는 실제 행 수와 예..

    [MySQL] 히스토그램 통계로 편향 컬럼의 행 수 추정치를 교정하는 방법

    MySQL 히스토그램: 실무적 정의와 운영상 중요성MySQL에서 히스토그램(Histogram)은 컬럼 값의 분포를 버킷 단위로 저장하는 옵티마이저 통계이다. 특히 인덱스가 없는 편향 컬럼의 조건절 선택도(Selectivity)를 추정할 때 사용된다. 동일한 값이 균등하게 분포한다고 가정하기 어려운 상태 코드, 지역, 등급, 처리 상태 컬럼이 대표적인 대상이다.독자가 확인하려는 핵심은 히스토그램이 행 수 추정치를 얼마나 개선하는가이다. 정해진 개선 비율은 없다. 개선 폭은 데이터 편향도, 조건값의 빈도, 버킷 수, 샘플링 비율과 통계 최신성에 따라 달라진다. 따라서 생성 전후의 추정 행 수를 실제 행 수와 비교하여 오차 배수로 판단해야 한다.히스토그램은 인덱스를 생성하지 않는다. 조건 컬럼에 인덱스가 없다..

    [MSSQL] 비클러스터드 인덱스의 Index Seek와 Table Scan 손익분기점 분석

    비클러스터드 인덱스: 실무적 정의와 운영상 중요성MSSQL에서 비클러스터드 인덱스(Nonclustered Index)는 인덱스 키와 행 위치 정보로 구성된 별도 B-Tree 구조이다. 검색 조건의 선택도(Selectivity)가 높으면 필요한 키 범위만 탐색하는 Index Seek가 효율적이다. 그러나 인덱스에 없는 컬럼까지 반환하면 원본 행을 다시 찾는 Key Lookup 또는 RID Lookup이 추가된다.반환 행이 증가하면 Seek 비용은 일정하게 유지되지 않는다. 인덱스 탐색 이후 각 행에 대한 Lookup과 데이터 페이지 접근이 반복되기 때문이다. 반면 Table Scan은 힙(Heap)의 데이터 페이지를 처음부터 끝까지 순차적으로 읽으며, 읽어야 할 전체 페이지 수를 기준으로 비용이 형성된다...

    [MySQL] 낮은 선택도 인덱스에서 Full Table Scan을 선택하는 기준과 검증 방법

    낮은 선택도 인덱스: 실무적 정의와 운영상 중요성MySQL에서 인덱스가 존재한다는 사실은 해당 인덱스가 항상 사용된다는 의미가 아니다. 옵티마이저는 후보 실행 계획별 비용을 계산하고, 인덱스 접근보다 전체 테이블 스캔(Full Table Scan)의 예상 비용이 낮으면 type=ALL을 선택한다.선택도(Selectivity)는 조건이 전체 행 중 얼마나 적은 행을 반환하는지를 나타낸다. 실무에서는 조건 일치 행 수 ÷ 전체 행 수로 반환 비율을 계산하며, 반환 비율이 낮을수록 선택도가 높다고 표현한다. 서로 다른 값의 수를 의미하는 카디널리티(Cardinality)와 선택도는 관련되지만 동일한 지표는 아니다.예를 들어 상태 컬럼에 값이 세 종류만 존재해도 특정 값이 전체의 극소수라면 그 조건은 높은 선택..

    [MSSQL] DMV로 미사용·중복 인덱스를 판별하는 방법: user_seeks 해석과 삭제 기준

    MSSQL 미사용·중복 인덱스 DMV: 실무적 정의와 운영상 중요성MSSQL에서 sys.dm_db_index_usage_stats는 인덱스별 사용자 조회와 갱신 활동을 누적해서 보여 주는 동적 관리 뷰(DMV)이다. user_seeks, user_scans, user_lookups, user_updates와 각 작업의 마지막 수행 시각을 확인할 수 있다.user_seeks가 낮다는 사실만으로 인덱스를 삭제하면 안 된다. 이 값은 인덱스의 필요성을 평가한 결과가 아니라 현재 DMV 관찰 구간에서 Seek 연산이 기록된 횟수이다. SQL Server 재시작 이후에 실행되지 않은 월말 배치, 장애 대응 쿼리, 분기별 정산, 특정 파라미터 구간의 조회는 수치에 반영되지 않을 수 있다.또한 인덱스는 Seek 외에..

    [MySQL] Invisible Index로 중복 인덱스 삭제 전 영향 범위를 검증하는 절차

    Invisible Index: 실무적 정의와 운영상 중요성MySQL에서 Invisible Index는 인덱스 구조와 유지 작업은 그대로 보존하면서 옵티마이저의 일반적인 실행 계획 후보에서만 제외하는 기능이다. 인덱스를 즉시 DROP하지 않고도 해당 인덱스가 사라진 상황을 먼저 검증할 수 있다. 중복 인덱스 정리 과정에서 복구 시간이 긴 재생성 작업을 피할 수 있다는 점이 핵심이다.Invisible 상태에서도 INSERT, UPDATE, DELETE가 발생하면 인덱스 엔트리는 계속 갱신된다. 따라서 쓰기 비용과 저장 공간은 감소하지 않는다. 이 기능은 삭제 효과를 측정하는 수단이 아니라, 읽기 쿼리의 실행 계획 회귀와 의존 범위를 검증하는 안전장치이다.검증 순서는 삭제 후보 선정, 기준 실행 계획 저장, ..

    [MSSQL] INCLUDE 컬럼 설계로 Key Lookup 병목을 제거하는 판단 기준

    INCLUDE 컬럼: 실무적 정의와 운영상 중요성MSSQL에서 Key Lookup은 비클러스터형 인덱스(Nonclustered Index)에서 검색 조건을 만족하는 행을 찾은 뒤, SELECT에 필요한 나머지 컬럼을 가져오기 위해 클러스터형 인덱스에 다시 접근하는 연산이다. Heap 테이블에서는 같은 목적의 RID Lookup이 발생한다. 검색 행마다 반복되는 임의 페이지 접근이므로 반환 행이 증가할수록 논리 읽기와 CPU 사용량이 함께 증가한다.INCLUDE 컬럼은 비클러스터형 인덱스의 리프 레벨에 조회용 컬럼을 저장한다. 검색 키 순서에는 참여하지 않지만 쿼리에 필요한 컬럼을 인덱스 내부에서 모두 반환할 수 있게 한다. 이 상태를 커버링 인덱스(Covering Index)라고 하며, 적절히 설계하면 ..