카테고리 18

복합 인덱스 = 조건 컬럼 순서는 정말 상관없을까? (100만 건으로 직접 검증!)

1. 왜 검증하게 됐나'친절한 SQL 튜닝'을 읽으며 = 조건으로 묶인 컬럼끼리는 인덱스 순서를 바꿔도 I/O에 영향을 주지 않는다는 내용을 접했다. 해당 내용은 '헷갈리는 부분 정리' 카테고리에 발행해 두었다.🔗 복합 인덱스에서 = 조건 컬럼의 순서는 왜 상관없을까?soo-archiving.tistory.com/20이론으로는 이해했지만 머리로 아는 것과 눈으로 보는 건 다르다고 생각해서 직접 가상의 데이터를 만들고 실행계획을 떠서 정말 그런지 확인해보기로 했다.2. 검증 환경 만들기노트북에 Orange툴이 있었지만 사용 기간이 한달짜리 트라이얼 버전이라 나중에도 지속적으로 쓸 환경이 필요했다. 그래서 Docker로 Oracle을 띄우고 SQL Developer로 접속하는 방식을 택했다. CMD에서 도..

소트 머지 조인

인덱스의 본질은 "정렬" — 소트 머지 조인으로 이해하기1. 소트 머지 조인은 정말 PGA를 쓸까?소트 머지 조인의 정렬 작업은 PGA의 Sort Area에서 수행된다 단 한 가지 단서가 있다정렬할 데이터가 너무 커서 Sort Area에 다 담기지 못하면 Temp Tablespace(디스크)로 흘러나간다 흔히 말하는 disk sort다그래도 정렬 연산의 주체는 어쨌든 PGA다그런데 "ORDER BY 때문에" 정렬되는 건 아니다여기서 처음 오해했던 부분이 있다 소트 머지 조인의 정렬은 사용자가 작성한 ORDER BY 절 때문에 일어나는 게 아니다옵티마이저가 조인을 수행하기 위해 조인 키 기준으로 양쪽 집합을 내부적으로 정렬하는 것이다 즉 쿼리에 ORDER BY가 한 줄도 없어도 소트 머지 조인이 선택되면 ..

복합인덱스 컬럼순서

복합 인덱스에서 = 조건 컬럼의 순서는 왜 상관없을까?복합 인덱스를 설계하다 보면 흔히 "선택도(Selectivity)가 높은 컬럼을 앞에 둬라"는 조언을 듣는다. 하지만 이 말이 항상 맞는 건 아니다. 적어도 = 조건으로 묶인 컬럼들 사이에서는, 어떤 컬럼이 앞에 오든 인덱스 스캔 효율에 영향을 주지 않는다이 글에서는 그 이유를 B-Tree 인덱스의 수직 탐색 / 수평 탐색 관점에서 데이터를 직접 펼쳐보며 정리한다예제 상황다음과 같은 조건절을 처리한다고 하자.WHERE 고객등급 = :V1 -- = 조건AND 고객번호 = :V2 -- = 조건AND 거래일자 >= :V3 -- 범위(BETWEEN) 조건고객등급과 고객번호는 항상 = 조건이고 거래일자는 범위 조건이다. 이때 인덱스를 다음 둘 ..

NL조인, 인덱스, 디스크 I/O

인덱스를 통해 rowid를 얻고 테이블액세스를 한다는 건 알고 있었다. 그러나 인덱스의 B-Tree 구조를 통해 수직탐색을 할 때도 I/O가 발생하는 건지 궁금했다. 이 부분을 정리해 보려고 한다.1. 인덱스를 이용해 테이블을 액세스 한다는 의미두 단계를 거친다인덱스 블록을 읽어 rowid를 얻는다획득한 rowid로 테이블 블록을 읽는다실행계획은 이렇게 작성된다INDEX RANGE SCAN OF 사원_X1 ← 인덱스 블록 읽기TABLE ACCESS BY INDEX ROWID OF 사원 ← rowid로 테이블 블록 읽기별개의 동작이 아니라 하나의 세트다.2. 디스크 I/O는 언제 발생하는가?오라클은 인덱스나 디스크 블록이 필요할 때 다음 순서로 동작한다먼저 버퍼캐시를 확인버퍼캐시에 있으..

IN 조건이 '=' 조건이 아닌 이유 - 인덱스 컬럼 순서

IN 조건이 '=' 조건이 아닌 이유 - 인덱스 컬럼 순서같은 IN 조건이라도 인덱스를 어떻게 구성하느냐에 따라 동작 방식과 비용이 완전히 달라진다--책 예시select * from 고객별가입상품where 고객번호 = :cust_no and 상품ID in ('NH00037', 'NH00041', 'NH00050')고객별 평균 카디널리티가 3이라고 가정 Case 1: 「상품ID + 고객번호」 인덱스[리프 블록 A] [리프 블록 B] [리프 블록 C]NH00037, 1230 NH00041, 1100 NH00050, 1234NH00037, 1234 ← NH00041, 1234 ← ..

IN 조건은 '=' 조건이 아닌이유 - BETWEEN, IN-List

1.BETWEEN을 IN-List로 바꾸면 항상 좋을까?선두 컬럼이 BETWEEN조건이면 후행 컬럼을 인덱스에서 거를 수 없어 비효율이 발생한다고 한다.-- 친절한SQL튜닝 책 예시-- BETWEEN 방식where 인터넷매물 between '1' and '3' and 아파트시세코드 = 'A01011350900056' and 평형 = '59' and 평형타입 = 'A'-- IN-List 방식where 인터넷매물 in ('1', '2', '3') and 아파트시세코드 = 'A01011350900056' and 평형 = '59' and 평형타입 = 'A'BETWEEN을 IN-List로 바꾸면 옵티마이저는 IN-List Iterator 방식으로 풀면서 각 값마다 모든 컬럼을 '='조건으로 검색한다. ..

오라클 SQL 분석정보 정리

1. 실행계획 (Execution Plan) - "예상"옵티마이저가 SQL을 어떻게 처리할지 세운 계획. 실제 실행 전 예측지.주요컬럼Operation: 처리 방식 (TABLE ACCESS FULL, INDEX RANGE SCAN, HASH JOIN 등)Rows (E-Rows) : 옵티마이저 예상 행 수Cost : 옵티마이저 비용Bytes / Time : 예상 데이터량 / 예상 시간2. 수행통계 (Runtime Statistics) - "실제"SQL이 실제로 돌고 난 뒤의 결과 수치. 예상(E) vs 실제(A)2-1. GATHER_PLAN_STATISTICS + DBMS_XPLAN.DISPLAY_CURSOR실행계획 각 줄(오퍼레이션 단계)마다 통계가 붙어서 나온다--예시쿼리SELECT /*+ GATHER..

[sqlp]/오라클 2026.05.09

주어진 배열과 빈 배열

주어진 배열 String[] = strArr텍스트 빈 배열 String[] answer = {}; String answer[] = new String[strArr.length];-> answer 빈 배열을 strArr과 같은 크기로 만들겠다는 뜻-> str은 입력값, answer은 가공해서 채워줄 새 배열answer[i] = strArr[i].toLowerCase()-> strArr[i]는 원래 주어진 값-> 소문자로 가공해서 answer[i]에 넣는다는 의미대소문자 변환 함수toLowerCase() 소문자 변환toUpperCase() 대문자 변환