SELECT (REPEATABLE-READ;반복 읽기)MySQL 서버에서 select 구문은 기본적으로 '잠금 없는 일관된 읽기'를 지원한다. 이는 격리 수준에 따라 레코드 버전이 달라지는데, commit-read 격리 수준에서는 가장 최근에 커밋된 데이터를 반환하지만 repeatable-read 수준에서는 트랜잭션이 시작된 시점의 데이터를 반환한다. 즉 repeatable-read 격리 수준에서는 select 문장이 하나의 트랜잭션에 내에서 여러 번 실행되어도 항상 동일한 결과를 반환한다.Tip)'잠금 없는 일관된 읽기;Non-Locking Consistent Read(MVCC)'는 테이블의 레코드를 읽을 때 대상 레코드에 대해 잠금을 거지 않고도 일관된 데이터 읽기를 지원하는 것을 의미. 예를 들어 ..
Study/[무럭무럭 시즌 2] Real MySQL 8.0
저작권 문제로 단순 강의 & 책 정리 글은 보호합니다!MySQL에서는 인덱스가 있음에도 불구하고 인덱스를 사용하지 못하고 Table Full-Scan으로 처리되는 경우가 있다. 어떤 경우가 있는지 살펴보자. 쿼리에서 컬럼이 가공되는 경우쿼리에서 컬럼이 가공되는 경우에는 해당 컬럼에 인덱스가 존재해도 인덱스를 사용하지 못하게 된다. 이는 인덱스가 컬럼의 원본 값을 기반으로 구성되어 있는데 수행된 연산 결과가 인덱스 데이터로 인덱싱되어 있지 않기 때문이다.-- 컬럼의 산술 연산 select * from exam_tab where id + 10 < 100 -- 함수의 인자로 직접 사용 select * from exam_tab where MOD(id, 2) = 0 -- 자동 형변환 select * from exam_tab where exam_string_col =..
UUID와 B-Tree 인덱스와의 관계UUID는 버전과 관계 없이 모두 랜덤한 값을 생성한다. 물론 UUID 버전 1에선 짧은 시간 동안 단조 증가하는 값을 생성하지만 7분 간격으로 리셋되기 때문에 계속 랜던한 값이 생성된다. 그리고 UUID는 128비트, 즉 16바이트 이진값으로 구성되어 있지만 일반적으로 가독성을 위해 16진수 문자열로 변환하여 DBMS에 저장하는 편이다. 결과적으로 16진수 문자열을 저장하기 위해 char(32) 혹은 binary(16) 타입을 사용하고 있는 것이다.Tip)국제인터넷 표준화 기구인 IETF에서 정식 표준으로 채택된 UUID는 5개의 버전이 있다. 그 중 버전 1과 버전 4를 자주 쓴다고 한다. 그래서 1과 4 버전의 특징만 간단하게 말하자면 UUID 1 버전은 Tim..
PreparedStatementPrepared statement는 orm 도구에서 많이 사용되는 것으로 binding query라고도 불린다. 이는 하기와 같이 값이 바인딩 되는 변수에 물음표를 사용해서 SQL 문장을 작성하고 prepare 단계를 먼저 수행한 후 변수의 값을 바인딩해서 쿼리를 실행하는 형태이다.pstmt = connection.prepareStatement( "select * from exam_tab where id = ?");pstmt.setInt(1, 1234);rs = pstmt.executeQuery(); 이처럼 prepared statement를 사용하여 쿼리를 작성하는 경우 빠르고 간단하게 sql injection 방지 처리를 구현할 수 있다. 그리고 쿼리 파싱 비용을 줄인..
LEFT JOIN을 사용하였지만 INNER JOIN?제목 그대로 left join을 사용하였지만 inner join이 동작한 것처럼 결과가 반환되는 경우가 있다. 예를 들어, user table과 coupon table이 있다고 가정해보자. 이때 user table과 coupon table은 하기와 같은 user_coupone table이란 매핑 테이블로 연관 지어져 있다.create table user_coupone ( user_id int not null, coupon_id int not null, ... primary key (user_id, coupon_id) key idx_coupon_id (coupon_id)); 이때 user table의 데이터 건수는 약 10,000 rows이고..
보호되어 있는 글입니다.
잘못된 기대일반적으로 'count(*)' 쿼리가 'select *' 보다 가벼울 것이라 기대한다. 하지만 대부분은 성능이 거의 동일한 경우가 많다. 또한 limit 조건 없이 사용되는 count 쿼리와 달리 select 쿼리의 경우 일반적으로 limit 조건이 걸린 후 사용되는 경우가 많기 때문에 성능면에서 count가 더 안좋은 경우가 있다. 심지어 ORM에서 자동 생성된 쿼리를 실행하면 하기 코드와 같이 distinct 쿼리가 자동 생성되어 사용되는 경우도 있다. count(*)의 경우에는 레코드 건수만 확인하면 되지만 count(distinct column)은 임시 테이블을 생성해 테이블의 레코드를 임시 테이블로 중복을 제거하면서 복사 후 레코드 건수를 반환하기 때문에 성능적으로 보면 훨씬 안좋다...
CHAR vs VARCHARchar와 varchar는 공통적으로 문자열을 저장할 때 사용하는 타입이다. 이때 최대 저장 가능 길이를 명시하는데, MySQL에서는 바이트 수를 의미하는 것이 아니라 문자의 최대 저장 갯수를 의미하는 것을 주의해야 한다. 다음으로 차이점을 살펴보면 char의 경우에는 고정된 길이의 문자열을 저장하는 반면 varchar는 가변 길이의 문자열을 저장한다. 예를 들어, char(10)와 varchar(10)이라고 했을 때 char의 경우에는 입력된 문자열 데이터 크기와 상관없이 나머지 공간이 공백 문자 데이터가 채워지면서 10 만큼의 공간을 고정으로 할당받고 varchar의 경우에는 입력된 문자열 데이터 크기에 맞춰 가변적으로 공간이 할당된다. 또한 최대 길이도 다르다. char의..
보호되어 있는 글입니다.