ํผ๋๋ก ๋์๊ฐ๊ธฐ
Dev.toDatabase
์๋ฌธ ์ฝ๊ธฐ
PostgreSQL FTS ๋์ ์ผ๋ก ์ธ๋ถ ๊ฒ์ ์์ง ์์ด 1,000๋ง ๊ฑด ๋ฐ์ดํฐ ์ฒ๋ฆฌ
Stop Paying for Algolia: Master PostgreSQL Full-Text Search ๐
AI ์์ฝ
Context
B2B SaaS ํ๋ซํผ์ ๊ฒ์ ๊ธฐ๋ฅ ๊ตฌํ์ ์ํด Algolia, Elasticsearch ๋ฑ ์ธ๋ถ ์ ์ฉ ๊ฒ์ ์์ง ๋์ ์ ๊ฒํ ํจ. ์ธ๋ถ ์๋น์ค ์ด์ฉ ์ ๋ฐ์ํ๋ ๋ฐ์ดํฐ ๋๊ธฐํ ๋ณต์ก์ฑ, ์คํจ ํ ๊ด๋ฆฌ ๋ถ๋ด ๋ฐ ์ ๊ตฌ๋ ๋น์ฉ์ด๋ผ๋ ์ํคํ ์ฒ์ ์ค๋ฒํค๋ ๋ฐ์.
Technical Solution
- Full Table Scan์ ์ ๋ฐํ๋ SQL LIKE ์ฐ์ฐ์ ๋์ฒดํ๊ธฐ ์ํด PostgreSQL Full-Text Search(FTS) ์ฑํ
- ํ ์คํธ๋ฅผ ์ ๊ทํ๋ ๋ฃจํธ ๋จ์ด ๋ฆฌ์คํธ๋ก ๋ณํํ๋ tsvector ํ์ ์ Generated Column ์ค๊ณ
- ๋ฐ์ดํฐ ์ฝ์ ๋ฐ ์์ ์ ์๋ ์ ๋ฐ์ดํธ๋ฅผ ๋ณด์ฅํ๋ STORED ์์ฑ ์ ์ฉ์ผ๋ก ๋๊ธฐํ ๋ก์ง ์ ๊ฑฐ
- ๊ฒ์ ์๋ ์ต์ ํ๋ฅผ ์ํด tsvector ์ปฌ๋ผ์ GIN Index๋ฅผ ์์ฑํ์ฌ ๋ฐ๋ฆฌ์ด ๋จ์์ ์๋ต ์๊ฐ ํ๋ณด
- title(A)๊ณผ content(B)์ ์๋ก ๋ค๋ฅธ ๊ฐ์ค์น๋ฅผ ๋ถ์ฌํ์ฌ ๊ฒ์ ๊ฒฐ๊ณผ์ Relevance Rank ์ต์ ํ
- websearch_to_tsquery ํจ์๋ฅผ ํตํ ๊ตฌ๊ธ ์คํ์ผ์ ์์ฐ์ด ๊ฒ์ ์ฟผ๋ฆฌ ์ธํฐํ์ด์ค ๊ตฌํ
์ค์ฒ ํฌ์ธํธ
1. ๋ฐ์ดํฐ ๊ท๋ชจ๊ฐ 1,000๋ง ๊ฑด ๋ฏธ๋ง์ธ ๊ฒฝ์ฐ ์ธ๋ถ ๊ฒ์ ์์ง๋ณด๋ค DB ๋ด์ฅ FTS ์ฐ์ ๊ฒํ
2. GIN Index๋ฅผ ํ์ฉํด ๊ฒ์ ์ฑ๋ฅ์ ํ๋ณดํ๊ณ ์๋์ง ํ์ธ
3. Generated Column์ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ๊ณ์ธต์ ๋๊ธฐํ ์ฝ๋ ์ ๊ฑฐ ๊ฐ๋ฅ์ฑ ๊ฒํ
4. ts_rank ํจ์๋ฅผ ํ์ฉํ ๊ฐ์ค์น ๊ธฐ๋ฐ ์ ๋ ฌ ์ ์ฉ ์ฌ๋ถ ํ์ธ