SQL을 실행할 때, 어떤 테이블을 먼저 읽고(드라이빙 테이블, Driving Table), 어떤 테이블을 나중에 조회(드라이븐 테이블, Driven Table)할지에 따라 실행 속도가 달라집니다.특히 Nested Loop Join에서는 조인 순서가 직접적인 성능에 큰 영향을 줍니다. 옵티마이저는 기본적으로 조인 순서를 자동으로 결정합니다.단, SQL 문에 힌트가 없을 경우입니다. 힌트나 통계 정보가 있다면 그것을 기반으로 옵티마이저가 판단을 조정할 수 있습니다. 조인 순서가 중요한 이유 드라이빙 테이블(Driving Table)의 선택이 실행 속도를 좌우함드라이빙 테이블의 크기가 작을수록 성능이 좋아짐.작은 테이블을 먼저 읽고, 그 결과를 기반으로 큰 테이블을 조회하면 Index Lookup을 최소화할..
INNER JOIN SELECT A.*FROM TableA AINNER JOIN TableB B ON A.id = B.id; INNER JOIN은 두 테이블을 결합한 후, 조인 조건에 맞는 레코드만 반환합니다.조인 시 TableB의 중복된 id가 있으면 TableA의 해당 레코드가 여러 번 중복 반환될 수 있습니다.실행 계획에서 JOIN 연산이 수행되며, 인덱스가 적절히 설정되지 않으면 성능 저하 가능성이 있습니다.EXISTSSELECT A.*FROM TableA AWHERE EXISTS (SELECT 1 FROM TableB B WHERE A.id = B.id); EXISTS는 TableB에서 A.id = B.id 조건을 만족하는 레코드가 존재하는지만 체크합니다.서브쿼리에서 SELECT 1을 사용하여..
Oracle에서 SQL 조인이 실행될 때, 논리적 조인(Logical Join)(예: INNER JOIN, LEFT JOIN)은 물리적 조인(Physical Join) 방식으로 변환되어 실행물리적 조인은 데이터를 실제로 처리하는 방법이며, Oracle의 옵티마이저가 가장 효율적인 방식을 자동으로 선택1. Nested Loop Join (중첩 루프 조인)🔹 기본 개념:외부 테이블의 각 행을 내부 테이블과 비교하여 일치하는 행을 찾는 방식작은 데이터셋이나 내부 테이블에 인덱스가 있는 경우 효율적일반적으로 인덱스가 존재하는 경우 자동 선택됨🔹 동작 방식:외부 테이블의 첫 번째 행을 가져옴내부 테이블에서 조인 조건을 만족하는 행을 찾음 (Index Lookup 가능)반복하여 모든 행을 처리SELECT /*+..
DispatcherServlet Spring MVC의 핵심 요소인 DispatcherServlet은 Front Controller 역할을 하며,모든 요청을 중앙에서 처리하고 적절한 컴포넌트로 분배하는 역할1. DispatcherServlet 동작 개요클라이언트가 HTTP 요청을 보내면 DispatcherServlet이 이를 가로채고, 내부적으로 여러 컴포넌트(HandlerMapping, HandlerAdapter, ViewResolver 등)를 사용하여 요청을 처리한 후 응답을 반환합니다.2. DispatcherServlet의 요청 처리 흐름① 클라이언트 요청 수신클라이언트가 GET /api/users 같은 HTTP 요청을 보냅니다.Spring Boot 애플리케이션에서는 DispatcherServlet이..
기본적인 예외 처리 흐름Spring MVC에서 컨트롤러 또는 서비스 계층에서 예외가 발생하면, DispatcherServlet이 이를 감지하고 적절한 방식으로 처리합니다.컨트롤러 또는 서비스에서 예외 발생HandlerExceptionResolver가 예외를 처리할 수 있는지 확인등록된 예외 처리 로직(@ExceptionHandler, @ControllerAdvice 등) 실행예외가 처리되지 않으면 기본적인 Spring 예외 처리(DefaultHandlerExceptionResolver) 실행그래도 해결되지 않으면, sendError()를 호출하여 기본적인 HTTP 에러 응답 반환예외 처리 우선순위Spring MVC에서 예외가 발생하면 아래 순서로 처리됩니다.@ExceptionHandler (컨트롤러 단위..
MySQL 8.0 이상에서만 사용 가능배열 내 모든 객체를 검사 가능{ "list": [ { "couponInfo": { "couponNo": "12345" } }, { "couponInfo": { "couponNo": "" } } ]}SELECT t.*FROM your_table yt,JSON_TABLE( yt.your_column, '$.list[*]' COLUMNS ( couponNo VARCHAR(255) PATH '$.couponInfo.couponNo' )) AS tWHERE JSON_VALID(yt.your_column) -- 유효한 JSON 데이터만 처리 AND t.coup..
@ValidJava의 표준 Bean Validation API(javax.validation.Valid)에서 제공단일 객체(단순 DTO)에 대한 유효성 검사 수행중첩 객체(내부 객체)도 함께 검사그룹(group) 검증 기능 없음import jakarta.validation.Valid;import jakarta.validation.constraints.NotNull;import jakarta.validation.constraints.Size;public class UserDto { @NotNull private String name; @Size(min = 6, message = "비밀번호는 최소 6자 이상이어야 합니다.") private String password; // Get..
readValue()Jackson에서 JSON을 DTO 클래스(POJO)에 매핑할 때 사용String json = "{ \"id\": 1, \"name\": \"Alice\", \"age\": 28 }";ObjectMapper mapper = new ObjectMapper();User user = mapper.readValue(json, User.class);convertValue()JsonNode를 POJO 또는 Map/Collection으로 변환하는 메서드JsonNode node = mapper.readTree(json);User user = mapper.convertValue(node, User.class);Jackson 내부적으로는:JsonNode를 중간에 직렬화(serialization) → J..
Jackson의 3가지 JSON 처리 모델모델특징장점단점Streaming API빠른 처리, 메모리 효율가장 빠름, 대용량 데이터에 적합사용법이 복잡하고 직관적이지 않음Tree Model유연한 구조 탐색 가능구조가 복잡하거나 동적일 때 유용전체 JSON을 메모리에 올려야 함Data Binding자바 객체 ↔ JSON 자동 매핑가장 사용하기 쉬움속도는 스트리밍보다 느림Streaming API (스트림 기반 처리)Streaming API는 Jackson에서 가장 저수준이며, 빠르고 메모리 효율적입니다. JSON을 한 줄씩 읽고 쓰는 방식 (JsonParser, JsonGenerator)으로 동작스트리밍 방식(Forward-only 방식)을 사용하면 메모리 사용량이 적습니다. 대용량 JSON 처리에 적합pull..
무한대 크기 지원: long 범위(±9경)를 넘는 정수도 표현 가능이론적으로 메모리가 허용하는 한 무한대에 가까운 숫자까지 표현불변 객체(Immutable): 기존 값을 바꾸지 않고 항상 새로운 객체를 반환정수 연산 지원: 덧셈, 뺄셈, 곱셈, 나눗셈, 나머지, 거듭제곱, GCD 등 다양한 연산 지원java.math 패키지에 포함import java.math.BigInteger;public class Main { public static void main(String[] args) { BigInteger big1 = new BigInteger("9223372036854775808"); // long 범위 넘어선 수 BigInteger big2 = new BigInteger(..