데이터베이스의 조회 성능을 끌어올리기 위해서 가장 우선적으로 검토되는 것이 "인덱스"다. 칼럼에 인덱스를 설정하면 왜 조회 성능이 빨라지는지 비유적으로 이해해 보자. # 책의 목차 비유 1000장이 넘는 데이터베이스 책이 있다고 가정하자. 책의 구성은 트랜잭션, 인덱스, 샤딩, 파티셔닝 등 다양하다. 이때, 우리는 인덱스 관련 부분만 읽고 싶다. 이럴 때 우리는 목차를 찾아가서 인덱스 관련 부분이 몇 페이지에 존재하는지 확인 후 곧바로 해당 페이지로 이동한다. 목차를 보니, 320페이지부터 인덱스 관련 내용이 시작이다. 이를 바탕으로 처음부터가 아니라 320페이지부터만 훑어보면 된다. 만약 목차가 없다면 어떻게 할까? 처음부터 하나씩 페이지를 훑어보면서 인덱스 관련 주제가 나오는지 찾아봐야 할 것이다. ..
프로젝트에서 복잡한 쿼리를 위해 보통 QueryDSL이나 MyBatis를 사용한다. MyBatis를 사용하는 경우 select 결과를 dto로 바로 받을 수 있는데, 이때 간혹 코틀린의 dto 클래스 (data class)의 프로퍼티 선언 순서와 select 절의 값 순서가 동일해야만 매핑되는 경우가 있다. 이런 경우는 어떤 경우이며 왜 그런지 살펴보자 (데이터베이스는 오라클을 기준) # 예시 세팅 다음과 같은 SQL을 가정해보자 SELECT A_V AS firstValue, B_V AS secondValue FROM table; 그리고 마이바티스로 이를 받아올 DTO는 다음과 같다고 해보자 data class Dto( val firstValue: String, val secondValue: String..
회사에서 사용하는 디비가 용량 이슈가 생겼던 적이 있는데, 그 당시 대강 보니 80TB 정도였다. 그래서 문득 1억건 정도 되는 데이터는 용량이 얼마나 될까?라는 생각을 가지게 되어서 테스트를 해보았다. 테이블 필드 타입, 수 그리고 인덱스 유무에 따라 다르겠지만, 그냥 가늠용으로 참고만 하면 좋을 것 같다. 디비는 MySQL이고 테스트 테이블은 위와 같이 생겼다. 여기에 write_date는 인덱스를 걸어놨다. 테스트 데이터는 7600만건 정도 넣어봤다. 해당 데이터는 AI허브에서 제공하는 인터넷 말뭉치 데이터인데, JSON형태로 제공해줘서 반복문으로 쉽게 집어넣었다. JDBC 배치 insert로 넣으니 50만건 넣는데 10초정도 걸렸다. (7600만 / 50만 = 152 * 10초 = 1520초 = ..
JPA 자체만으로는서 동일한 키 값을 가지는 두 엔티티를 조회했을때 동일성을 보장해주지 않는다. 따라서 로직상 동일한 키를 가지는 두 엔티티를 비교하기 위해선 반드시 equals와 hashCode를 재정의해야한다. # 단일키일 경우 다음과 같은 PK로 하나의 값을 가지는 엔티티를 가정해보자. @Entity data class OneKeyEntity( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long = 0L ) 이제 이 코드를 실행해서 리포지토리에서 가져온 동일한 두 ID 엔티티가 동일한지 확인해보면, val oneKeyFirst = oneKeyEntityRepository.findById(1).orElseThrow() val on..
회사에서 오라클 디비를 사용하는데, 날짜를 계산하는 비즈니스 로직이 대부분 오라클 내장함수인 add_months()함수를 통해서 이루어지고 있었다. 이 함수는 날짜를 정확하게 계산하지 못 하는 문제가 있었는데 이를 개선했던 경험을 공유하고자 한다. # 계산 일이 말일일 경우 발생하는 오류 우선 비즈니스 요구사항이 6개월후를 의미하는 건, 정확히 응당일로 결과나 나와야 하는 것이였다. 쉽게말해 2023.02.28 -> 6개월 후 -> 2023.08.28로 결과가 나와야 했다. add_months()함수는 이 부분을 충족하지 못하고 있었는데, 'yyyymmdd'포맷의 날짜의 6개월 후를 add_months()함수를 사용해서 나오는 결과를 살펴보자 1월 (31) → 7월 (31) 정상 2월 (28) → 8월 ..
소프트 딜리트를 구현하다 보면 테이블의 칼럼을 하나 추가해서 상태값으로 삭제인지, 아닌지를 판별한다. 예를 들어서 Archive라는 테이블이 삭제되면 visibility라는 칼럼의 true / false 상태로 이를 구분한다. 이후 전체조회를 할 때 삭제된 레코드들은 SELECT 하면 안 되므로, visibility=true 조건을 WHERE 조건에 걸어줘야 할 것이다. 도메인이 많아질수록, 소프트 딜리트를 구현한 테이블에 전체 조회 로직이 많을 수록 쿼리는 점점 길어질 것이다. # 해결방법 엔티티 클래스에 @Where 어노테이션을 달아주면, 조회를 할 때 해당 조건을 타고 가져오게 된다. clause 부분에 WHERE 조건을 탈 조건문을 문자열로 넣어주면된다. 나는 Visibility라는 클래스로 변수..
Redis는 인메모리 데이터 key-value 저장소로, 모든 데이터를 메모리에 관리해서 매우 빠른 성능을 자랑하는 NoSQL 데이터베이스다. 나는 "인 메모리"라는 점에서 의문점이 생겼다. 즉, Redis에 저장된 데이터는 Redis 서버가 다운되면 사라지는가? 로컬로 key를 저장하고 재부팅 후 데이터를 조회하면 남아있는 걸 발견했다. 그래서 의문점이 생겨서 교수님께 질의응답을 진행한 내용을 공유하고자 한다. 결론부터 말하자면, "그렇지 않다" Redis 서버가 다운되더라도 데이터는 보존된다. 이는 Redis Persistance와 연관이 있다. 이와 관련한 질의응답 내용은 아래와 같다. 결국 Redis의 시작은 완전한 인 메모리 DB에서 시작됐지만, 사용자의 니즈에 따라 변화된거로 이해하면 될 것 ..