[PostgreSQL] ์ธ๋ฑ์Šค: Gin

postgres์˜ ์ธ๋ฑ์Šค ํƒ€์ž…์—๋Š” btree, ํ•ด์‹œ ์™ธ์—๋„ ๋…ํŠนํ•œ 2๊ฐ€์ง€ ํƒ€์ž…์ด ์กด์žฌํ•œ๋‹ค.
๋ฐ”๋กœ Gist์™€ Gin์ด๋‹ค.
์—ฌ๊ธฐ์„  ์‚ฌ์šฉ์„ฑ์ด ์ข€๋” ๊ดœ์ฐฎ์€ Gin์„ ๋จผ์ € ๋‹ค๋ค„๋ณด๊ฒ ๋‹ค.

์šฐ์„  ํ…Œ์ŠคํŠธํ•  ํ…Œ์ด๋ธ” ์ƒํƒœ๋Š” ์ด๋ ‡๋‹ค.

๋ณ„๊ฑฐ์—†๋‹ค. ๊ฐ’์€ 10๋งŒ๊ฐœ๋งŒ ๋„ฃ์–ด๋’€๋‹ค.



Gin์ด๋ž€?

Gin์€ Generalized Inverted Index์˜ ์ถ•์•ฝ์œผ๋กœ, ๋ฒˆ์—ญํ•˜๋ฉด "์ผ๋ฐ˜ํ™”๋œ ๊ฐ„๊ฒฉ ์ธ๋ฑ์Šค"๊ฐ€ ๋œ๋‹ค.
๋ง ๊ทธ๋Œ€๋กœ ๊ฐ’(ํŠนํžˆ ๋ฌธ์ž์—ด)์„ ์ผ์ •ํ•œ ๊ฐ„๊ฒฉ์œผ๋กœ ์ชผ๊ฐœ์„œ ์ธ๋ฑ์Šค๋ฅผ ๋ณต์žกํ•œ ์กฐ๊ฑด์—์„œ๋„ ํƒˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์‚ฌ์‹ค Gin์ด๋‚˜ Gist๊ฐ™์€ ํŠน์ˆ˜ํ•œ ์ธ๋ฑ์Šค๋“ค์€ ์ผ๋ฐ˜์ ์ธ ์šฉ๋„๋กœ๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์€ ์นœ๊ตฌ๋“ค์ด๋‹ค. ๋ง‰ ๋ฐฐ์—ด์ฒ˜๋ฆฌ๋‚˜ ๋ณต์žกํ•œ ์ปค์Šคํ…€์ด ํ•„์š”ํ• ๋•Œ ์ฃผ๋กœ ์“ฐ๋Š”๋ฐ,
Gin์€ ์ผ๋ฐ˜์ ์ธ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ผ€์ด์Šค๊ฐ€ ํ•˜๋‚˜ ์žˆ๋‹ค.

๋ฐ”๋กœ ํ…์ŠคํŠธ ํŒจํ„ด๊ฒ€์ƒ‰์ด๋‹ค.

์•ž์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด, ์ผ๋ฐ˜ ์ธ๋ฑ์Šค์˜ ๊ฒฝ์šฐ์—๋Š” LIKE '%ํ…์ŠคํŠธ%' ๊ฐ™์€ ์กฐ๊ฑด์—๋Š” ์ธ๋ฑ์Šค ์Šค์บ”์„ ํ•˜์ง€ ๋ชปํ•œ๋‹ค. text_pattern_ops๋ผ๋Š” ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•ด๋„ %๊ฐ€ ํŒจํ„ด ์•ž์— ๋ถ™์€ ๊ฒƒ์€ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•œ๋‹ค.

ํ•˜์ง€๋งŒ Gin ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ทธ๋Ÿฐ ์ƒํ™ฉ์—์„œ๋„ ์ธ๋ฑ์Šค๋ฅผ ํƒœ์šธ ์ˆ˜๊ฐ€ ์žˆ๋‹ค.


๋˜ํ•œ, Gin์€ ์ผ๋ฐ˜ ์ธ๋ฑ์Šค์ฒ˜๋Ÿผ ๊ทธ๋ƒฅ ๋‹ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ์—ฐ์‚ฐ์ž ํด๋ž˜์Šค๋ผ๋Š” ๊ฒƒ์„ ์ง€์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

Gin์— ์‚ฌ์šฉํ• ๋งŒํ•œ ๋‚ด์žฅ ํด๋ž˜์Šค๋Š” array_ops, tsvector_ops, jsonb_ops, jsonb_path_ops ๋“ฑ์ด ์žˆ์œผ๋‚˜, ์ด๊ฒƒ๋“ค์€ ๋ฌธ์ž์—ด์— ์“ฐ๊ธฐ ํž˜๋“  ๊ฒƒ๋“ค์ด๊ณ .

๋ฌธ์ž์—ด ๊ฒ€์ƒ‰์—๋Š” pg_trgm์ด๋ผ๋Š” ํ™•์žฅ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ„ํŽธํ•˜๊ณ  ๊ดœ์ฐฎ์€ ํŽธ์ด๋‹ค. ์ด๊ฑด ๋ฌธ์ž์—ด์„ 3๊ธ€์ž์”ฉ ์ชผ๊ฐœ์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.



pg_trgm์„ ์ด์šฉํ•œ ๊ฒ€์ƒ‰

์ƒ์„ฑ์€ ์•„๋ž˜์™€ ๊ฐ™์ด ํ•˜๋ฉด ๋œ๋‹ค.
create extension์œผ๋กœ ๋จผ์ € pg_trgm ํ™•์žฅ์„ ํ™œ์„ฑํ™”ํ•˜๊ณ , ์ธ๋ฑ์Šค ์ƒ์„ฑ์‹œ์— ์—ฐ์‚ฐ์ž ํด๋ž˜์Šค gin_trgm_ops๋ฅผ ๋ถ™์—ฌ์ฃผ๋ฉด ๋œ๋‹ค.

๊ทธ๋Ÿผ

ํ’€์Šค์บ”์„ ํ•ด์„œ 9์ดˆ๊ฐ€ ๋„˜๊ฒŒ ๊ฑธ๋ฆฌ๋˜ ๊ฒƒ์ด


์ธ๋ฑ์Šค๋ฅผ ํƒ„ ๋น„ํŠธ๋งต ์Šค์บ”์œผ๋กœ 1์ดˆ๋„ ๊ฑธ๋ฆฌ์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.

์—ฌ๊ธฐ์„œ ์•ฝ๊ฐ„ ์ฃผ์˜ํ•  ์ ์ด ์žˆ๋Š”๋ฐ

pg_trgm์€ 3๊ธ€์ž ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์œ„์™€ ๊ฐ™์ด ๊ธ€์ž๊ฐ€ 3๊ธ€์ž ๋ฏธ๋งŒ์ด๋ฉด ์ธ๋ฑ์Šค๋ฅผ ํƒ€์ง€ ๋ชปํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๊ทผ๋ฐ ์‚ฌ์‹ค 1๊ธ€์ž๋‚˜ 2๊ธ€์ž ์ •๋„์˜ ๊ฒ€์ƒ‰ ํŒจํ„ด์€ ๊ฒ€์ƒ‰๋ฒ”์œ„๊ฐ€ ๋„ˆ๋ฌด ๋„“๊ธฐ ๋•Œ๋ฌธ์— ์˜คํžˆ๋ ค ํ’€์Šค์บ”์ด ๋น ๋ฅผ ํ™•๋ฅ ์ด ๋†’๋‹ค.
๊ทธ๋ž˜์„œ ํฐ ๋ฌธ์ œ๋Š” ์—†๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค.




tsvector ํƒ€์ž…์„ ์ด์šฉํ•œ ์ „์ฒด ํ…์ŠคํŠธ ๊ฒ€์ƒ‰

tsvector์˜ ts๋Š” text search์˜ ์ถ•์•ฝ์ด๋‹ค. ๋ง ๊ทธ๋Œ€๋กœ ํ…์ŠคํŠธ ๊ฒ€์ƒ‰์„ ์œ„ํ•œ ๋ฒกํ„ฐ๋ผ๋Š” ๋ง์ด๋‹ค.
์‹ค์ œ ์ฒ˜๋ฆฌ๋ฐฉ์‹์ด๋‚˜ ์‚ฌ์šฉ๋ฒ•์ด ๋‹ค ๋ฌธ์ž์—ด์˜ ๋ฐฐ์—ด์ด๋ผ์„œ ๋‹จ์ˆœํ•œ ๋ฌธ์ž์—ด๋งŒ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ๋ผ๋ฉด ๊ณผ๋„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค...

์ด๊ฑด ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ธด ๋ฌธ์žฅ์—์„œ 'ํŠน์ • ๋‹จ์–ด'๋งŒ์„ ๊ฒ€์ƒ‰ํ•  ๋•Œ ์ ํ•ฉํ•œ ๋ฐฉ์‹์ด๋‹ค.

์ด๊ฑด like ๋Œ€์‹  @@ ์—ฐ์‚ฐ์ž์™€ tsquery ๊ฐ’์œผ๋กœ ๊ฒ€์ƒ‰์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
์•„๋ž˜์˜ tsquery๋Š” 16์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ…์ŠคํŠธ๋งŒ ์ฐพ๋Š” ์ฟผ๋ฆฌ๋‹ค.

๊ทผ๋ฐ ํ›„ํ–‰ ์™€์ผ๋“œ ์นด๋“œ๋Š” ๋˜๋Š”๋ฐ ์„ ํ–‰ ์™€์ผ๋“œ์นด๋“œ๋Š” ์ž˜ ์•ˆ๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค?

์ด๊ฒƒ๋„ gin ์ธ๋ฑ์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž

์ด๊ฑด ์—ฐ์‚ฐ์ž ํด๋ž˜์Šค๋ฅผ ๋”ฐ๋กœ ์ง€์ •ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ๋งŒ๋“œ๋Š” ๊ฒŒ ๊ฐ€๋Šฅํ•˜๋‹ค.


๊ทธ๋Ÿผ ๋น„ํŠธ๋งต์ด ์ž˜ ๋œฐ ๊ฒƒ์ด๋‹ค.

๊ทธ๋ ‡๋‹ค.


์ฐธ์กฐ
https://medium.com/vuno-sw-dev/postgresql-gin-%EC%9D%B8%EB%8D%B1%EC%8A%A4%EB%A5%BC-%ED%86%B5%ED%95%9C-like-%EA%B2%80%EC%83%89-%EC%84%B1%EB%8A%A5-%EA%B0%9C%EC%84%A0-3c6b05c7e75f
https://stackoverflow.com/questions/1566717/postgresql-like-query-performance-variations
https://dba.stackexchange.com/questions/10694/pattern-matching-with-like-similar-to-or-regular-expressions-in-postgresql/10696#10696
https://www.postgresql.org/docs/9.5/textsearch.html