2024-04-16-TIL
2024-04-16-TIL
Today I Learned
HashJoin
- https://en.wikipedia.org/wiki/Hash_join
- https://coding-factory.tistory.com/758#google_vignette
- https://velog.io/@eunhye_/SQL-%EC%A1%B0%EC%9D%B8Join-%EC%88%98%ED%96%89-%EC%9B%90%EB%A6%AC
해시 조인은 두 테이블을 조인할 때 한쪽으로 해시 테이블을 만들고, 다른 쪽을 훑으면서 해시 테이블을 찾아보는 조인 알고리즘이다. 두 단계로 나뉜다.
- Build : 두 입력 중 (조건을 적용한 뒤) 더 작은 쪽을 읽어 조인 키로 해시 테이블을 만든다.
- Probe : 다른 쪽 입력을 한 행씩 읽으며, 같은 키를 가진 행을 해시 테이블에서 찾아 결합한다.
각 테이블을 한 번씩만 읽으면 되므로, 바깥 테이블의 행마다 안쪽 테이블을 뒤지는 중첩 루프 조인(Nested Loop Join)보다 대체로 빠르다. 대신 해시로 같은 값을 찾는 방식이라 a.id = b.id 같은 동등 조건(equi-join)에 맞고, 작은 쪽이 메모리에 들어가야 효율이 난다.
MySQL은 8.0.18부터 해시 조인을 지원한다. 조인 조건에 쓸 인덱스가 없을 때 예전의 Block Nested-Loop 대신 해시 조인을 쓰고, 8.0.20부터는 동등 조건이 없는 조인에도 쓴다. 사용하는 메모리는 join_buffer_size를 넘지 않고, 넘치면 디스크 파일을 쓴다. 실행 계획에서 해시 조인이 쓰였는지는 EXPLAIN FORMAT=TREE로 확인한다. 결국 인덱스가 있는 조인이면 인덱스를 타는 중첩 루프가, 인덱스 없이 큰 테이블끼리 동등 조건으로 붙일 때는 해시 조인이 유리하다고 정리했다.
Spring Data JPA findById Anti-Pattern
- https://medium.com/javarevisited/spring-data-jpa-findbyid-anti-pattern-aefbf045fc44
글의 첫 번째 지적은 여러 엔티티를 가져올 때 findById를 반복해서 부르면 id 개수만큼 쿼리가 나간다는 것이다. 이럴 때는 findAllById(ids)로 IN 조건 한 번에 가져오는 편이 낫다.
두 번째 지적은 findById가 영속성 컨텍스트에 이미 있는 엔티티도 매번 새로 만든다는 것인데, 이 부분은 표준 명세와 맞지 않는다. Jakarta Persistence의 EntityManager.find는 엔티티가 영속성 컨텍스트에 있으면 거기서 돌려준다고 명시한다. 같은 트랜잭션 안에서 같은 id로 다시 조회하면 1차 캐시의 같은 인스턴스가 나온다.
관련해서 알아 둘 메서드가 getReferenceById다. 연관관계만 걸면 되고 엔티티의 내용은 필요 없을 때 쓴다. 조회 쿼리 없이 참조(프록시)를 돌려주고, 실제로 없는 id라면 처음 접근할 때 EntityNotFoundException이 날 수 있다. 예전의 getOne, getById는 deprecated되고 이 메서드로 대체됐다.
AI 키워드: Claude 3
Anthropic이 3월 4일 Claude 3 모델군을 발표했다. 성능 순으로 Haiku, Sonnet, Opus 세 모델을 두고, 쓰임새에 따라 지능, 속도, 비용 사이에서 고르게 했다. 하나의 모델이 아니라 크기가 다른 모델을 한 세대로 묶어 내놓고, 실시간 응답에는 작은 모델을 쓰라는 식으로 선택지를 준다는 말이구나.
댓글
아직 댓글이 없습니다