Database 53

Real MySQL - Limit, Offset 절의 동작 원리! (+ No Offset 성능 비교)

LIMIT Limit 절은 쿼리 결과에서 지정된 순서에 위치한 레코드만 가져오고자 할 때 사용한다. 아래의 예제를 보자. SELECT * FROM employees WHERE emp_no BETWEEN 10001 AND 10010 ORDER BY first_name LIMIT 0, 5; 위의 쿼리는 다음과 같은 순서로 실행된다. employees 테이블에서 WHERE 절의 검색 조건에 일치하는 레코드를 전부 읽어 온다. 1번에서 읽어온 레코드를 first_name 칼럼값에 따라 정렬한다. 상위 5건이 정렬이 완료되면 즉시 쿼리를 멈춘다. 정렬된 결과의 상위 5건만 사용자에게 반환한다. Oracle의 ROWNUM과 달리 MySQL의 LIMIT은 항상 쿼리의 마지막에 실행된다. 즉, 데이터 전체를 조회해서 ..

Database/SQL 2022.06.26

Real MySQL - BETWEEN문 튜닝하는 방법! (with MySQL Server 8.0)

BETWEEN BETWEEN은 특정 범위를 스캔할 때 주로 사용한다. 개인적으로 IN절에서 여러 개의 값을 전부 명시하는 것보다 BETWEEN처럼 범위로 한 번에 당겨오는 것이 성능상 좋을 것이라고 생각했었다. 정말 그런지 살펴보자. BETWEEN vs IN 절 dept_emp 테이블에 (dept_no, emp_no)로 구성된 PK가 있다고 가정하자. 아래의 SQL 문을 보자. SELECT * FROM dept_emp WHERE dept_no BETWEEN 'd003' AND 'd005' AND emp_no=10001; 문제는 BETWEEN은 범위 안에 있는 모든 레코드를 읽는다는 점이다. 해당 조회는 먼저 BETWEEN으로 모든 레코드를 읽은 후에 emp_no로 조건을 비교한다. 즉, 많은 데이터가 메..

Database/SQL 2022.06.26

Database - 트랜잭션의 특징 (ACID)

트랜잭션 ? 트랜잭션은 데이터베이스에서 하나의 그룹으로 처리되어야 하는 명령문들을 모아 놓은 논리적인 작업 단위이다. 여러 개의 명령어의 집합이 정상적으로 처리되면 정상 종료되며 하나의 명령어라도 잘못되면 전체가 롤백된다. 트랜잭션을 사용하는 이유 데이터의 일관성을 유지하면서 안정적으로 데이터를 복구하기 위함이다. 데이터베이스에선 테이블에서 데이터를 읽어 온 후 다른 테이블에 데이터를 입력하거나 갱신, 삭제하는데 처리 도중 오류가 발생하면 모든 작업을 원상태로 되돌린다. 처리 과정이 모두 성공했을 때만 최종적으로 데이터베이스에 반영한다. 락(Lock) 트랜잭션을 사용하는 이유가 전체 단위를 롤백만 하기 위한 것은 아니다. DB 락이라는 것이 있는데 여러 사용자가 동일한 데이터를 액세스할 때 작업이 순차적..

Database/SQL 2022.06.25

MySQL - 커버링 인덱스

커버링 인덱스 커버링 인덱스(Covering Index)는 원하는 데이터를 인덱스에서만 추출할 수 있는 인덱스를 의미한다. B-Tree 스캔만으로 원하는 데이터를 가져올 수 있으며, 칼럼을 읽기 위해 실제 데이터 블록에 접근할 필요가 전혀 없다. 인덱스는 행 전체 크기보다 훨씬 작고 인덱스 값에 따라 정렬이 되기 때문에 Sequential Read로 접근할 수 있기 때문에 쿼리 성능을 크게 향상할 수 있다. 그래서 인덱스를 설계한다고 해서 WHERE 절에 국한된 문제가 아니라, 사실 쿼리 전체에 대해 인덱스 설계가 필요하다. 예시 테이블 생성 create table user ( id int(11) not null auto_increment, name varchar(20) not null default '..

Database/SQL 2022.05.31

Real MySQL - 옵티마이저란 무엇인가 ? (+ 기본 데이터 처리)

옵티마이저(Optimizer) MySQL에서 쿼리의 결과는 동일하지만 내부적으로 그 결과를 만들어내는 방법은 매우 다양하다. 그런 방법 중에서 어떤 방법이 최적이고 최소의 비용이 소모될 지 결정해야 한다. 쿼리를 최적으로 실행하기 위해 각 테이블의 데이터가 어떤 분포로 저장돼 있는지를 참조하고, 데이터를 기반으로 최적의 실행 계획을 수립해주는 것이 옵티마이저(Optimizer)이다. 어떤 DBMS든 쿼리의 실행 계획을 수립하는 옵티마이저는 가장 복잡한 부분으로 알려져있다. 하지만 실행 계획을 이해해야 실행 계획의 불합리한 부분을 찾아내고, 더 최적화된 방법으로 실행 계획을 수립하도록 유도할 수 있다. 쿼리 실행 절차 MySQL 서버에서 쿼리가 실행되는 과정은 크게 세 단계로 나눌 수 있다. SQL문을 잘..

Database/SQL 2022.05.13

SQL - Using Temporary, Using Filesort 정리 (+ 임시 테이블, 파일 정렬)

Using Temporary, Using Filesort Explain 문으로 실행 계획을 확인하면, 늘 눈에 거슬리는 것이 Using Temporary, Using Filesort이다. 이것들이 왜 발생하고 어떠한 영향이 있는 지 알아보자. 임시 테이블(Using Temporary) MySQL 엔진이 스토리지 엔진으로부터 받아온 레코드를 정렬하거나 그룹핑 할 때는 내부적인 임시 테이블을 사용한다. MySQL 엔진이 사용하는 임시 테이블은 처음에는 메모리에 생성됐다가 테이블의 크기가 커지면 디스크로 옮겨진다. 원본 테이블의 스토리지 엔진과 관계없이 임시 테이블이 메모리를 사용할 때는 MEMORY 스토리지 엔진을 사용하며, 디스크에 저장될 때는 MyISAM 스토리지 엔진을 이용한다. 다음은 임시 테이블이 ..

Database/SQL 2022.05.11

SQL - SELECT 쿼리 실행 순서 정리!

SELECT 쿼리문은 FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY 총 6단계를 거친다. 아래는 각 단계의 동작을 정리한 것이다. FROM 절 (+ Join) 쿼리의 첫번째 실행 순서는 FROM절이다. FROM 절에서는 조회할 테이블을 지정합니다. 이후 Join을 실행하여 하나의 가상 테이블로 결합합니다. WHERE 절 WHERE 절에서는 테이블에서 조건에 맞는 데이터를 필터링한다. GROUP BY GROUP BY 절에서는 선택한 칼럼을 기준으로 조회한 레코드 목록을 그룹핑한다. HAVING 절 HAVING 절은 그룹핑 후에 각 그룹에 사용되는 조건 절이다. 쉽게 말해 그룹을 필터링한다고 생각하면 된다. HAVING 절의 조건을 WHERE 절에도 사용할 수 있는 경..

Database/SQL 2022.05.11

Database의 책임 - DB는 어디까지 해줘야 하는가? (+ 데이터 가공, 비즈니스 로직, 계산 등)

Database의 책임 이전부터 비즈니스 로직이 어디에 있어야 하는지는 큰 관심사였다고 한다. 나는 Controller, Service, Repository, Dto 등의 책임에 대해서 자료를 많이 봤지만 "DB는 어떤 작업까지 처리하는 것이 바람직한가?" 그러한 생각을 해본적이 없었다. 우리 회사의 서비스들을 보면 DB에서 SELECT절에서 CONCAT()이나 IF()를 통해 가공해서 내려주는 경우가 많다. 그래서 그것을 프론트단에서 아주 손쉽게 사용할 수 있다. 추가적으로 복잡한 비즈니스 로직을 DB Layer에서 태우는 경우도 있다. 뭔가 Application Layer에서 로직을 태우면 선형으로 순회하면서 레코드 하나씩 가공을 해줘야 한다는 부담감 때문이었다. 데이터베이스(Database)의 책임..

Database/Server 2022.05.06

트랜잭션은 언제 시작되고 언제 종료되는가? (트랜잭션 시작 시점과 종료 시점)

트랜잭션(Transaction) 종료 시점 "트랜잭션은 언제 종료되는가"에 대해 알아보자. 먼저 트랜잭션의 종료 시점을 알아보기에 앞서 시작 시점을 먼저 알아보자! 트랜잭션이 자동으로 시작되는 시점은 아래와 같다. DML(INSERT, UPDATE, DELETE) 문장이 실행되는 경우 DDL(CREATE, ALTER, DROP) 문장이 실행되는 경우 DCL(GRANT, REVOKE) 문장이 실행되는 경우 트랜잭션은 아래와 같은 상황에 자동으로 종료 된다. COMMIT, ROLLBACK 문을 실행한 경우 DDL 또는 DCL 문 실행 기계 장애 또는 시스템 충돌(crash) deadlock 발생 강제 종료 DDL(Create, Alter, Drop, Truncate) 또는 DCL(Grant, Revoke)문..

Database/SQL 2022.05.02

Database - 교착상태 문제를 해결하는 방법!

DB(데이터베이스)에서의 교착상태 운영체제에서 교착상태(Dead Lock)는 각각의 프로세스가 서로의 자원을 점유하기 위해 대기하면서 문제가 발생한다 DB(데이터베이스)에서 교착상태는 여러 개의 트랜잭션(Transaction)들이 실행을 하지 못하고 서로 무한정 기다리는 상태를 의미한다. 트랜잭션 1이 테이블 B에 insert하게 되면서 첫 번째 행의 Lock(잠금)을 얻는다. 트랜잭션 2도 테이블 A의 첫 번째 행의 Lock(잠금)을 얻는다. Transaction 1> start transaction; insert into B values(1); Transaction 2> start transaction; insert into A values(1); 여기서 트랜잭션을 commit 하지 않은채 서로의 첫..

Database/SQL 2022.04.20