Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BLOOM-114] 지역검색 쿼리 fulltext search 적용 #115

Merged
merged 4 commits into from
Sep 16, 2024

Conversation

stophwan
Copy link
Member

Close #114

How

  • 지역 검색 쿼리에 FullText Search를 적용하였습니다.
  • 현재 지역 검색 쿼리는 LIKE '%지역명% 방식이었습니다. 해당 방식은 와일드카드가 앞에 존재함으로서 인덱스를 적용하기 어렵고, '서울 송파' 와 같은 쿼리 시에는 아무런 값도 반환하지 않는 문제점이 존재합니다.

Result

  • FullTextIndex의 ngram parser를 적용하였습니다.

  • 해당 방식은 Text에 대해 토큰 사이즈만큼 자른 후 인덱스를 생성하는 방식입니다.(Ngram token size는 1로 설정했습니다)

  • '서울 가락'과 같은 방식으로 검색 시 다음과 같은 쿼리를 생성하고 올바른 결과를 반환합니다.
    SELECT id, name FROM region WHERE MATCH(region.name) AGAINST('+서울 +가락' IN BOOLEAN MODE)
    스크린샷 2024-09-16 오후 4 28 21

  • 속도 차이는 다음과 같습니다.
    사진의 첫번째 줄 마지막 시간이 해당 쿼리가 완료된 시간(ms)인데요. 여러번 실행의 평균값을 놓는다고 해도 20ms->0.5ms로 97.5% 성능 개선이 이루어졌습니다.

    • LIKE문
      EXPLAIN ANALYZE SELECT id, name FROM region WHERE name LIKE '%송파%' LIMIT 30;
      스크린샷 2024-09-16 오후 4 38 47
    • FullText Index
      EXPLAIN ANALYZE SELECT id, name FROM region WHERE MATCH(region.name) AGAINST('+송파' IN BOOLEAN MODE) LIMIT 30;
      스크린샷 2024-09-16 오후 4 37 40

고민사항

다음과 같은 내용을 고민했습니다.

  • 자모분리를 사용하지 않은 이유
    식물 검색시 처럼 자모분리를 해서 검색을 진행하려고 했으나 다음과 같은 문제가 있었습니다.
    • 'ㅅㅓ'를 검색한 결과입니다. IndexFull Search를 할 시 '서'가 포함된 모든 칼럼들이 순서를 고려하지 않고 반환되어서 사용자에게 혼란을 줄 수 있다고 생각했습니다.
      SELECT id, name FROM region WHERE MATCH(region.decomposed_name) AGAINST('+ㅅㅓ' IN BOOLEAN MODE) LIMIT 30;
      스크린샷 2024-09-16 오후 4 52 17
    • 'ㅅㅓ'를 검색시 '성'이 포함되는 글자도 같이 검색이 되게 됩니다. 식물 검색과 같은 경우는 모르기 때문 혹은 정보를 찾기 위해 검색을 하지만, 주소 검색은 아는 주소를 빠르게 검색하는 것이 우선이기 때문에 자모분리를 하지 않는 것이 낫다고 판단했습니다.
  • Prefix Index를 사용할까 고민했습니다.
    • '서울특별시', '경기도'와 같은 1단계 지역과 '송파구'와 같은 2단계 지역구에 대해 인덱스를 설정하여 주소값을 빠르게 찾는 방법을 생각했습니다. 실제 1단계 지역구는 큰 카디널리티를 보여주었습니다.
    • 하지만 '서'를 검색했을 시 1단계, 2단계, 3단계 지역구에 대해 모두 검색이 이루어져야하기 떄문에 UNION을 사용해야했고, UNION과정에서 쿼리가 느려져 유의미한 개선이 이루어지지 않았습니다.

@stophwan stophwan added the 💊 refactor Suggest code improvements or refactoring label Sep 16, 2024
@stophwan stophwan self-assigned this Sep 16, 2024
@stophwan stophwan requested a review from Dompoo as a code owner September 16, 2024 08:00
Copy link
Collaborator

@Dompoo Dompoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호! 처음 보는 방식이라 신기하네요!! 저도 이것저것 찾아보니 좋은 방식이라는 생각이 듭니다.

하나 고민되는 지점이 있는데,
'서울 가락ㄷ' 처럼 한글을 다 완성시키지 않고 쿼리하게 되면 '+서울 +가락ㄷ' 으로 검색돼서 문제가 발생할 수도 있을 것 같은데, 문제가 발생하지는 않나요?

@Dompoo
Copy link
Collaborator

Dompoo commented Sep 16, 2024

오호! 처음 보는 방식이라 신기하네요!! 저도 이것저것 찾아보니 좋은 방식이라는 생각이 듭니다.

하나 고민되는 지점이 있는데, '서울 가락ㄷ' 처럼 한글을 다 완성시키지 않고 쿼리하게 되면 +서울 +가락ㄷ 으로 검색돼서 문제가 발생할 수도 있을 것 같은데, 문제가 발생하지는 않나요?

만약 문제가 생긴다면 createSearchQuery 메서드 실행 전에 ㄱㄴㄷㄹ . . . ㅏㅑㅓㅕ . . . 같은 미완성 한글은 String에서 제거하는 것도 괜찮을 것 같아요!
그렇게 되면 '서울 가락ㄷ' -> '서울 가락' -> '+서울 +가락'으로 파싱돼서 쿼리가 괜찮게 될 것 같습니다!

@stophwan
Copy link
Member Author

stophwan commented Sep 16, 2024

맞습니다. 사실 그래서 자모분리를 해야하나 말아야하나 고민이 굉장히 깊었었는데, 말씀하신 부분 굉장히 좋아보입니다!!
b4adcf4
반영했습니다!

Copy link
Collaborator

@Dompoo Dompoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 고생하셨습니다!

@stophwan stophwan changed the title [refactor] 지역검색 쿼리 fulltext search 적용 [BLOOM-114] 지역검색 쿼리 fulltext search 적용 Sep 16, 2024
@stophwan stophwan merged commit 8ac0cf4 into main Sep 16, 2024
1 check passed
@stophwan stophwan deleted the refactor/search_region branch September 16, 2024 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💊 refactor Suggest code improvements or refactoring
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[refactor] 지역 검색 FullTextIndex 적용
2 participants