본문 바로가기
Blog/TIL

2025-02-25 (화)

by 코젼 2025. 2. 25.
728x90
반응형

2025-02-25 (화)

TIL (Today I Learned) - DDL & 비즈니스 로직

💡 오늘 배운 핵심 요약 1️⃣ DDL을 작성할 때는 JOIN 최적화, FK 제약, INDEX 설계를 신중하게 고려해야 함

2️⃣ LEFT JOIN을 사용할 때 조건 필터링을 적절히 활용하여 성능 최적화

3️⃣ 비즈니스 로직에서 BATCH UPDATE를 활용하면 성능을 크게 개선 가능

4️⃣ 트랜잭션을 효과적으로 관리하여 데이터 정합성을 유지하는 것이 중요


1️⃣ DDL 작성 및 최적화

🔹 테이블 설계 시 고려한 사항

  • LEFT JOIN 최적화를 위한 인덱스 전략 수립
    • 자주 사용되는 JOIN 대상 컬럼에 인덱스 적용
    • 외래키 관계가 설정된 경우에도, 실제 쿼리 성능을 고려한 인덱스 추가 고려
  • 기본 키(PK)와 외래 키(FK) 설정 시 데이터 무결성 유지
    • 트랜잭션 중 FK 무결성 검증이 필요한 부분 정리
    • FK가 과도하게 걸리면 성능 저하될 수 있어, 참조 무결성과 성능 사이의 트레이드오프 고려
  • UNIQUE 제약 조건을 통한 중복 방지
    • 중복 데이터 방지를 위해 UNIQUE INDEX 활용
    • 일부 컬럼에 대해 NULL 허용 여부를 고려하여 적용

🔹 DDL 작성 중 주요 수정 사항

  • 데이터 타입 조정
    • DECIMAL(15,0) → DECIMAL(15) (일부 SQL 엔진에서 (0)을 허용하지 않음)
    • VARCHAR(N) 길이 조정 (비효율적인 길이를 줄여 성능 개선)
  • 기본값 설정 (DEFAULT) & ON UPDATE CURRENT_TIMESTAMP 사용
    • UPDATED_AT 컬럼을 ON UPDATE CURRENT_TIMESTAMP로 자동 갱신되도록 설정
    • 불필요한 NULL 허용을 최소화하여 데이터 무결성 유지
  • FK 제약 조건 추가 & ON DELETE CASCADE 고려
    • 일부 테이블에서 참조하는 부모 테이블 삭제 시 함께 삭제되도록 설정
    • 반대로, 일부 테이블에서는 데이터 보호를 위해 ON DELETE RESTRICT 적용

2️⃣ LEFT JOIN을 활용한 데이터 조회 최적화

🔹 비즈니스 로직을 위한 쿼리 최적화

  • 특정 비즈니스 개체의 상태를 조회하는데 JOIN을 많이 사용해야 하는 상황
    • 문제점: 서브쿼리가 많아지고, 일부 테이블에 대해 FULL TABLE SCAN 발생 가능성
    • 해결 방법:
      • LEFT JOIN 최적화: 조인 대상 테이블에 적절한 인덱스 추가
      • 필요 없는 컬럼은 SELECT에서 제외하여 불필요한 I/O 최소화
      • 조건을 ON 절에서 걸지 않고 WHERE 절에서 필터링하여 성능 향상

✅ 최적화 전 (비효율적인 쿼리)

SELECT A.id, A.name, B.status, C.value
FROM entity_a A
LEFT JOIN entity_b B ON A.id = B.entity_a_id
LEFT JOIN entity_c C ON B.id = C.entity_b_id
WHERE A.active = 1;

🔻 문제점

  • entity_b가 entity_a를 참조하지만, entity_c까지 포함되면서 불필요한 중복 데이터가 조회될 가능성
  • LEFT JOIN을 했지만, NULL 값이 발생하는 경우 필터링이 어렵다
  • entity_c에서 필요 없는 데이터를 가져오는 문제가 발생

✅ 최적화 후 (필요한 데이터만 조회)

SELECT A.id, A.name, B.status, COALESCE(C.value, 0) AS value
FROM entity_a A
LEFT JOIN entity_b B ON A.id = B.entity_a_id AND B.status = 'ACTIVE'
LEFT JOIN entity_c C ON B.id = C.entity_b_id AND C.type = 'PRIMARY'
WHERE A.active = 1;

🔹 개선된 점

  • LEFT JOIN 시 필요한 조건을 ON 절에 추가하여 필터링 최적화
  • NULL 값 처리를 위해 COALESCE(C.value, 0) 적용 (후처리 로직 필요 최소화)
  • 필요 없는 데이터를 JOIN 하지 않도록 조건을 추가하여 JOIN 부하 감소

3️⃣ 비즈니스 로직 구현 & 서비스 최적화

🔹 핵심 비즈니스 로직 개선

📌 기존 문제:

  • 특정 비즈니스 개체의 상태를 변경하는 로직이 일괄 업데이트가 아닌 단건 처리 방식으로 구현됨
  • 하나의 트랜잭션에서 다수의 쿼리가 실행되면서 성능 저하 발생

🚀 해결 방법: 1️⃣ 일괄 업데이트 (BATCH UPDATE) 활용

2️⃣ JOIN을 활용한 조건 기반 업데이트 최적화

3️⃣ 불필요한 조회 쿼리 제거 & 필요할 때만 SELECT 실행

✅ 최적화된 업데이트 쿼리

UPDATE entity_a A
JOIN entity_b B ON A.id = B.entity_a_id
SET A.status = 'INACTIVE'
WHERE A.active = 1 AND B.status = 'EXPIRED';

🔹 개선된 점

  • 기존 SELECT 후 UPDATE 구조에서 직접 JOIN을 활용하여 업데이트 최적화
  • JOIN을 사용해 entity_b의 상태를 확인하고, 조건이 맞는 경우에만 UPDATE 실행

4️⃣ 트랜잭션 최적화 (Kotlin + Spring)

🔹 트랜잭션 관리 문제 해결

📌 기존 문제:

  • 서비스에서 여러 개의 쿼리를 실행하는데, 일부만 실패해도 일관성이 깨지는 문제 발생
  • 트랜잭션 경계를 명확하게 설정하지 않으면, 부분적인 데이터만 반영될 위험이 있음

✅ 트랜잭션 적용 (@Transactional)

@Service
class BusinessService(
    private val repositoryA: EntityARepository,
    private val repositoryB: EntityBRepository
) {

    @Transactional
    fun updateBusinessStatus(businessId: String) {
        val entityA = repositoryA.findByBusinessId(businessId)
            ?: throw IllegalArgumentException("Invalid ID")

        entityA.status = "INACTIVE"
        repositoryA.save(entityA)

        repositoryB.updateStatusByBusinessId(businessId, "CLOSED")
    }
}

🔹 개선된 점

  • @Transactional 적용하여 하나의 트랜잭션에서 여러 개의 업데이트 처리
  • 예외 발생 시 롤백이 가능하여 데이터 무결성 보장
  • repositoryB.updateStatusByBusinessId() 메서드 내부에서 BATCH UPDATE 실행하여 성능 개선

5️⃣ DDL & 비즈니스 로직 개선 후 배운 점

✅ DDL 작성 시 중요한 점

  • FK, UNIQUE, DEFAULT 값 등 데이터 무결성 유지 & 성능 고려
  • LEFT JOIN을 고려한 인덱스 최적화 필요
  • DECIMAL, VARCHAR 등 데이터 타입을 신중하게 선택하여 스토리지 최적화

✅ 비즈니스 로직 최적화 핵심

  • JOIN을 적극적으로 활용하여 쿼리 개수 줄이기
  • BATCH UPDATE, @Transactional을 사용하여 데이터 정합성 유지
  • COALESCE(), ON UPDATE 등의 활용으로 후처리 로직 최소화

✅ 트랜잭션 설계 원칙

  • 트랜잭션 범위를 최소화하여 잠금 시간을 줄이고 성능 최적화
  • 하나의 트랜잭션에서 다수의 변경이 필요하면 BATCH UPDATE를 적극 활용
  • 예외 발생 시 롤백이 필요한 경우 @Transactional 적용하여 데이터 무결성 유지

6️⃣ 다음 액션 플랜

🔹 [1] ERD 다이어그램 개선은 완료, 다음으로 비즈니스 로직 최적화 진행

🔹 [2] DDL을 기반으로 INDEX, FK, UNIQUE 전략 문서화

728x90
반응형

'Blog > TIL' 카테고리의 다른 글

2025-02-28 (금)  (1) 2025.02.28
2024-02-24 (월)  (0) 2025.02.24
2025-02-21 (금)  (0) 2025.02.21
2025-02-20 (목)  (0) 2025.02.20
2025-02-19 (수)  (0) 2025.02.19

댓글