같은 MySQL 쿼리는 왜 처음만 느렸을까: InnoDB 버퍼 풀과 스토리지 읽기
닉네임 로직 리팩터링의 추가 쿼리 비용을 측정하다 발견한 첫 실행 지연을 통해, 버퍼 풀 hit가 줄이는 비용과 캐시로도 사라지지 않는 작업을 구분한다.
Technical writing
개념과 맥락을 다시 확인할 수 있도록 정리한 기술 글입니다.
닉네임 로직 리팩터링의 추가 쿼리 비용을 측정하다 발견한 첫 실행 지연을 통해, 버퍼 풀 hit가 줄이는 비용과 캐시로도 사라지지 않는 작업을 구분한다.
서로 반대되는 조회 옵션을 구현할 때 NOT으로 조건의 관계를 명확하게 표현하는 방법을 정리한다.
행마다 달라지는 날짜 하한 때문에 created_at 인덱스를 쓰지 못한 쿼리에, 기존 결과를 보존하는 고정 후보 범위를 추가한 근거를 보여준다.
비정상적인 extra_days 하나가 날짜 계산을 NULL로 만들거나 조회 범위를 넓힐 수 있어, 입력 검증과 인덱스 회귀 확인을 함께 둔 이유를 설명한다.
수정 전후 서버에 같은 fixture와 요청을 보내 배열 순서·커서·필드까지 비교하고, 성능 측정과 결과 검증을 분리한 방법을 보여준다.
AI 사이드 프로젝트에서 Flyway의 버전 순서를 유지하면서 out-of-order, 중복 SQL과 겹치는 배포를 CI·배포 큐·DB 제약으로 나눠 막은 판단을 다룬다.
tree는 같지만 부모 이력이 다른 환경 브랜치를 진단하고, 공유 이력을 force push 없이 --ff-only로 한 지점에 모은 방법을 설명한다.
전환기 호환 필터를 고정 context-path로 바꾸면서 prefix 매핑, 헬스체크와 컨텍스트 밖 접근 로그의 책임 이동을 검증한다.
AI에게 구현을 맡기기 전에 인수 조건과 예외 케이스를 정하고, 단위·통합 테스트로 완료 여부를 검증하는 방법.
2026년 4월 Claude Code의 /branch, 당시 /fork, /btw를 비교하고 이후 /fork와 /subtask의 역할이 바뀐 과정을 보충한다.
AI가 구현을 바꿔도 기능의 동작을 지키도록, 테스트 범위와 mock 사용 기준을 정리했다.
요구사항 확인, TDD, 정적·동적 검증과 PR 공유를 작은 스킬로 연결하되 작업 크기에 따라 단계를 줄이는 운영 방식을 보여준다.
범용 프레임워크의 계획·TDD·리뷰 원칙은 가져오되, 프로젝트별 SQL·호환성 검증은 작은 전용 스킬로 만든 판단을 설명한다.
Chrome DevTools MCP와 Playwright MCP를 세션, 디버깅 기능, 재현성, 브라우저 지원 관점에서 비교한다.
변경 명령 화이트리스트보다 읽기 명령 블랙리스트를 택한 이유와, 복합 Bash 명령을 안전하게 판별해야 하는 경계를 설명한다.
SessionStart·PostToolUse·matcher로 세션별 활동 로그를 만들고, matcher 밖 도구의 누락 가능성과 평문 로그 위험까지 함께 짚는다.
에디터와 언어 분석기를 JSON-RPC로 분리한 구조를 메시지 예제로 설명하고, IntelliJ와 Claude Code 연동이 LSP 서버가 아닌 이유를 구분한다.
published가 인덱스 밖에 있어 조건부 MAX 최적화가 깨진 원인과, 역순 인덱스 탐색이 유효한 데이터 분포 조건을 설명한다.
Java 스레드와 InnoDB 트랜잭션에서 잠금 순서가 엇갈릴 때 생기는 deadlock과 예방·복구 방법을 비교한다.
count++의 lost update를 출발점으로 synchronized, ReentrantLock, AtomicInteger와 CAS의 선택 기준을 비교한다.
원본 테이블 크기보다 필터 후 행 수·안쪽 인덱스 비용·EXPLAIN ANALYZE의 loops로 nested-loop 조인 순서를 판단한다.
Spring 조회 메서드에서 트랜잭션 유무가 커넥션 재사용, 읽기 일관성, readOnly 힌트와 비용에 어떤 차이를 만드는지 확인한다.
readOnly 조회 트랜잭션 안의 부수적인 쓰기가 REQUIRED와 REQUIRES_NEW에서 어떻게 달라지는지와 선택 기준을 살펴본다.
SELECT 사전 확인의 경쟁 조건을 유니크 키로 막고, 예상한 DuplicateKeyException만 도메인 중복으로 처리하는 기준을 제시한다.
Java 람다의 지역변수 캡처에서 effectively final과 definite assignment가 왜 별개의 규칙인지 바이트코드와 예제로 확인한다.
일반 SELECT와 UPDATE 사이의 경쟁을 MVCC 문제와 구분하고, 변경 조건을 UPDATE에 넣어 원자적으로 판정한 이유를 설명한다.
OFFSET 페이징에서 같은 행이 다시 보인 원인을 고유하지 않은 ORDER BY에서 찾고, 마지막 정렬 키와 커서 페이징을 비교한다.
재전송된 요청이 OPEN → OPEN도 성공으로 판정해 포인트를 두 번 차감한 원인과, 조건부 UPDATE로 한 번만 처리하게 한 방법을 보여준다.
sys.innodb_lock_waits, INNODB_TRX, 실행 계획을 연결해 waiter·blocker·잠긴 인덱스와 트랜잭션 시간을 찾는 순서를 제시한다.
한 트랜잭션이 행을 수정하는 동안 일반 SELECT와 locking read가 어떻게 다르게 동작하는지 InnoDB의 잠금과 MVCC로 설명한다.
한글 부분 검색에서 제한된 LIKE와 ngram FULLTEXT가 만드는 결과·토큰·색인 비용을 비교해, 이번에는 LIKE를 유지한 기준을 제시한다.
앞선 할당으로 바뀐 값을 다음 식이 읽는 MySQL 단일 테이블 UPDATE 동작과, 순서 의존 SQL을 테스트로 고정하는 기준을 제시한다.
setStatus나 sendError가 필터 실행을 끝내지 않는다는 점과 오버로드된 헬퍼의 실제 호출을 추적해, 거절 뒤 return이 필요한 이유를 설명한다.
max-age 이후 ETag와 If-None-Match로 캐시를 재검증하는 흐름과 Spring·URLSession에서 304가 다르게 보이는 이유를 다룬다.
RESTful API의 개념, 구성 요소, 장점, URI 설계 원칙을 정리한다.
Ajax, Axios, Fetch의 차이와 비동기 HTTP 요청 방식을 정리한다.
Head First Design Patterns의 전략 패턴 내용을 Java 예시와 함께 정리한다.
Gradle과 Maven의 차이, 빌드 흐름, 성능 특징을 정리한다.
JDK, JRE, JVM, JIT의 차이와 Java 실행 구조를 정리한다.
Lombok의 목적, 주요 어노테이션, 설정 방법을 정리한다.
Java에서 추상 클래스와 인터페이스를 언제 어떻게 구분해서 쓰는지 정리한다.
Spring JDBC와 JdbcTemplate의 역할과 사용 흐름을 정리한다.
IP, 서브넷, 서브넷 마스크, 네트워크 주소 계산을 정리한다.
JDBC의 역할, 실행 흐름, 드라이버와 커넥션 사용 방식을 정리한다.
SSH의 대칭키, 비대칭키, 공개키 인증 흐름을 정리한다.
HikariCP와 데이터베이스 커넥션 풀의 역할, 동작 과정, 설정 기준을 정리한다.
Java의 parseInt와 valueOf 차이를 Wrapper 클래스 관점에서 정리한다.
Linux crontab 사용법과 스케줄링 기본 개념을 정리한다.
Shell의 역할과 기본 개념을 정리한다.