본문 바로가기

DB

(8)
DB 병목 현상(DB Bottleneck) 정리 1. DB 병목 현상이란?DB가 시스템 전체 성능의 병목 지점이 되는 상황을 말합니다.쉽게 말해, 애플리케이션/웹 서버는 충분히 빠른데 DB가 트래픽을 감당하지 못해 전체 서비스 속도가 느려지는 현상입니다.2. 병목이 발생하는 주요 원인읽기 쿼리 과다동일한 데이터 반복 조회인덱스 미적용으로 Full Scan 발생쓰기/동시성 문제동시 INSERT/UPDATE/DELETE 요청 급증Lock 경합(예: InnoDB row lock, table lock)비효율적인 쿼리불필요한 JOIN, SELECT *WHERE 절에 함수 사용 (인덱스 무효화)GROUP BY/ORDER BY에서 임시 테이블·파일소트 발생커넥션 관리 문제PHP-FPM 등에서 커넥션이 과도하게 생성 → DB max_connections 초과커넥션 ..
MySQL 트랜잭션 격리 수준 정리 1. 트랜잭션이란?트랜잭션(Transaction)은 데이터베이스에서 하나의 논리적인 작업 단위를 말합니다.예를 들어, 계좌 이체는 출금 + 입금이 한 세트로 모두 성공해야만 완료되는 작업입니다. 데이터베이스에서 트랜잭션은 **ACID** 속성을 만족해야 합니다.**A**tomocity (원자성): 모두 성공하거나 모두 실패 **C**onsistency (일관성): 트랜잭션 전후 데이터 일관성 유지 **I**solation (격리성): 동시에 실행되는 트랜잭션 간 영향 최소화 **D**urability (지속성): 트랜잭션이 커밋되면 영구 반영 2. 격리 수준(Isolation Level)이란?격리 수준은 동시에 여러 트랜잭션이 실행될 때, 서로 간섭하지 않도록 하는 정도를 의미합니다.MySQL(Inn..
MySQL 인덱스 동작 원리(B-Tree 구조) 1. 인덱스란?인덱스(Index)는 **데이터 검색 속도를 빠르게 하기 위한 자료구조**입니다. MySQL(InnoDB)에서는 기본적으로 **B+Tree** 구조의 인덱스를 사용합니다. 2. B-Tree / B+Tree란?- **B-Tree**: 데이터와 포인터를 노드에 함께 저장하는 트리 구조 - **B+Tree**: B-Tree를 개선한 구조로, 리프 노드(leaf node)에 모든 데이터 저장 + 리프 노드끼리 연결 📌 MySQL InnoDB는 **B+Tree 인덱스**를 사용합니다. → 리프 노드에 **정렬된 데이터**가 있어 범위 검색이 빠름 3. B+Tree 인덱스 구조 [ Root Node ]↓[ Branch Node ]↓[ Leaf Node (정렬된 데이터, 포인터 연결) ] ..
[MySQL] UPSERT (INSERT ON DUPLICATE KEY UPDATE) 사용법 정리 예시 데이터 (users 테이블)CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, user_id VARCHAR(50) UNIQUE, name VARCHAR(100), gender CHAR(1)); [ { "user_id": "u001", "name": "Alice", "gender": "W" }, { "user_id": "u002", "name": "Bob", "gender": "M" }] 기존에 존재하면 업데이트, 없으면 삽입 (UPSERT)INSERT INTO users (user_id, name, gender)VALUES ('u002', 'Bobby', 'M')ON DUPLICATE KEY UPDATE name = VALUES(nam..
[MySQL] REPLACE 함수 사용법 정리 기본 문법REPLACE(str, from_str, to_str) str: 원본 문자열from_str: 바꿀 대상 문자열to_str: 대체할 문자열 1. 단순 문자열 치환SELECT REPLACE('Hello World', 'World', 'MySQL') AS result;-- 결과: 'Hello MySQL' 2. 컬럼 값 치환 (SELECT)SELECT user_id, REPLACE(name, 'a', '@') AS masked_nameFROM users;3. UPDATE 문에서 사용UPDATE usersSET name = REPLACE(name, 'a', '@')WHERE name LIKE '%a%';
[MySQL] CASE 사용법 정리 [ { "user_id": "u001", "name": "Alice", "labeled_name": "Alice (여성)" }, { "user_id": "u002", "name": "Bob", "labeled_name": "Bob (남성)" }, { "user_id": "u003", "name": "Carol", "labeled_name": "Carol (여성)" }]예시 데이터 (users 테이블)iduser_idnamegender1u001AliceW2u002BobM3u003CarolW 조건에 따라 값 설정하기 (CASE WHEN)SELECT user_id, name, CASE gender WHEN 'W' THEN '여성' WHEN 'M' THEN '남성' ELSE '기..
[MySQL] CONCAT(), GROUP_CONCAT() 사용법 정리 예시 데이터 (users 테이블) iduser_idname1u001Alice2u002Bob3u003Carol문자열 연결 (CONCAT)SELECT id, CONCAT(user_id, ' - ', name) AS user_infoFROM users; 결과[ { "id": 1, "user_info": "u001 - Alice" }, { "id": 2, "user_info": "u002 - Bob" }, { "id": 3, "user_info": "u003 - Carol" }]여러 행을 하나로 합치기 (GROUP_CONCAT)SELECT GROUP_CONCAT(name) AS all_namesFROM users; 결과[ { "all_names": "Alice,Bob,Carol" }] CONCAT과 함께..
[MySQL] JSON_EXTRACT() 사용법 정리 예시 데이터 (employees 테이블)idnamedetails (JSON)1Alice{ "age": 30, "address": { "city": "Seoul", "zipcode": "12345" } }2Bob{ "age": 25, "address": { "city": "Busan", "zipcode": "67890" } } 특정 키값만 추출 (SELECT)SELECT name, JSON_EXTRACT(details, '$.age') AS age FROM employees; 결과[ { "name": "Alice", "age": 30 }, { "name": "Bob", "age": 25 }] 특정 조건으로 필터링 (WHERE)-- age 값이 28보다 큰 경우만 추출 (zip..