๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

DB, ORM

์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ๊ฐœ์„ ํ•˜์—ฌ API ์‘๋‹ต 2.5์ดˆ์—์„œ 0.2์ดˆ๋กœ ๊ฐœ์„ ํ•˜๊ธฐ

์„œ๋ก 

์•ฝ 2.5์ดˆ๊ฐ€ ๊ฑธ๋ฆฌ๋˜ ๋Œ€ํ™” ๋ชฉ๋ก ์กฐํšŒ API์˜ ์‘๋‹ต ์‹œ๊ฐ„์„ 0.2์ดˆ๋กœ ๊ฐœ์„ ํ•˜๋ฉฐ ๋ฐฐ์šด ์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ์™€ Hash Join, Nested Loop Join ์˜ ํŠน์ง•์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ

๋Œ€ํ™” ๋ชฉ๋ก ์กฐํšŒ API๋ฅผ Postman์œผ๋กœ ํ…Œ์ŠคํŠธํ•œ ๊ฒฐ๊ณผ, ์‘๋‹ต ์‹œ๊ฐ„์ด ์•ฝ 2.5์ดˆ๋‚˜ ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.

 

์›์ธ ํŒŒ์•…

ํ•ด๋‹น API๋Š” DB ์ ‘๊ทผ์„ ์ด 3๋ฒˆ ํ•˜๋Š” ๊ตฌ์กฐ์˜€๊ธฐ์— ๋ณ‘๋ชฉ ์ง€์ ์„ ๋น ๋ฅด๊ฒŒ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด IntelliJ Profiler๋กœ ๊ฐ ์ฟผ๋ฆฌ์˜ ์‹คํ–‰ ์‹œ๊ฐ„์„ ์ธก์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

IntelliJ Profiler ๋กœ API ์‘๋‹ต์„ ์ธก์ •ํ•˜์—ฌ ๋‚˜์˜จ ์ฟผ๋ฆฌ ๋ณ„ ์‹œ๊ฐ„

์ธก์ • ๊ฒฐ๊ณผ

์ฒซ ๋ฒˆ์งธ ์ฟผ๋ฆฌ๋Š” ์•„๋ž˜ ์‚ฌ์ง„์˜ ์กฐํšŒ ์กฐ๊ฑด 5๊ฐ€์ง€(๊ฒ€์ƒ‰์–ด, ์„œ๋น„์Šค, ์นดํ…Œ๊ณ ๋ฆฌ ๋ช…, ์‚ฌ์šฉ์ž ๋ฐ˜์‘, ๋Œ€ํ™”์ผ์ž)๋ฅผ ํ•„ํ„ฐ๋งํ•ด์„œ ํŽ˜์ด์ง€ ๋‹น ๋ณด์—ฌ์ค„ ๋Œ€ํ™” UUID 10๊ฐœ๋ฅผ ์ถ”์ถœํ•˜๋Š” ์ฟผ๋ฆฌ๋กœ, 102ms ๊ฐ€ ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.

๋Œ€ํ™” ๋ชฉ๋ก ์กฐํšŒ ์‹œ, ํ•„ํ„ฐ๋ง ์กฐ๊ฑด 5๊ฐ€์ง€

 

๋‘ ๋ฒˆ์งธ ์ฟผ๋ฆฌ๋Š” ์•„๋ž˜ ์‚ฌ์ง„์˜ ๋Œ€ํ™” UUID ๋งˆ๋‹ค ์‚ฌ์šฉ์ž ๋ฐ˜์‘์„ ์ง‘๊ณ„ํ•˜๋Š” ์ฟผ๋ฆฌ๋กœ, 51ms ๊ฐ€ ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.

๋Œ€ํ™” ๋ชฉ๋ก ๊ฐ’

 

์„ธ ๋ฒˆ์งธ ์ฟผ๋ฆฌ๋Š” ๋Œ€ํ™” UUID ๋งˆ๋‹ค ์œ„ ์‚ฌ์ง„์˜ ์ตœ์ดˆ์งˆ์˜์™€ ๋‹ต๋ณ€์„ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๋กœ ๊ฐ€์žฅ ๋Šฆ์€ 2.3์ดˆ๊ฐ€ ๊ฑธ๋ ธ๊ณ , IntelliJ Profiler ๋ฅผ ํ†ตํ•ด ๋น ๋ฅด๊ฒŒ ๋ณ‘๋ชฉ์ง€์ ์„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

์›์ธ ๋ถ„์„

๋ฌธ์ œ ์ฟผ๋ฆฌ ์†Œ๊ฐœ

์„ธ ๋ฒˆ์งธ ์ฟผ๋ฆฌ๋Š” ์ƒ๊ฐ๋ณด๋‹ค ๋‹จ์ˆœํ–ˆ๋Š”๋ฐ 2.3์ดˆ๋‚˜ ๊ฑธ๋ ค์„œ ์˜์•„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฟผ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋Œ€ํ™”(Dialogue)์™€ ์ฑ„ํŒ…(Chat_log)์€ 1 : N ๊ด€๊ณ„

- ๋Œ€ํ™” UUID 10๊ฐœ๋งˆ๋‹ค ๊ณต๋ฐฑ์ด ์•„๋‹Œ ์ฑ„ํŒ…์„ ํ†ตํ•ด ์ตœ์ดˆ ์งˆ์˜๋ฅผ ์ฐพ๊ธฐ 

select c.*, d.*
from chat_log c
    join dialogue d on c.dialogue_id = d.id
where d.id IN ( -- ๋Œ€ํ™”(dialouge) UUID 10๊ฐœ
               '3f056f44-993c-49ce-9c35-8c64821ef270',
               ...
               '53186f20-784a-4f4b-bd0a-1e66061312eb')
      and c.seq = (
          select min(c2.seq)
          from chat_log c2
          where c2.question <> '' 
                and c2.dialogue_id = d.id -- ๋ฌธ์ œ์˜ ์›์ธ
      );

 

์‹คํ–‰ ๊ณ„ํš ๋ถ„์„

์‚ฌ์šฉ DB๋Š” PostgreSQL ์ด๋ฉฐ, EXPLAIN ANALYZE๋กœ ์‹คํ–‰๊ณ„ํš์„ ํ™•์ธํ•˜๋‹ˆ ์ฟผ๋ฆฌ๊ฐ€ ๊ธฐ๋Œ€ํ•œ ๋Œ€๋กœ ์‹คํ–‰๋˜์ง€ ์•Š์€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

์‹คํ–‰ ๊ณ„ํš์—์„œ ๊ฐ€์žฅ ๋‘๋“œ๋Ÿฌ์ง„ ๊ฒƒ์€ ์„œ๋ธŒ ์ฟผ๋ฆฌ๊ฐ€ 20๋ฒˆ ๋ฐ˜๋ณต๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์˜€์Šต๋‹ˆ๋‹ค.

```

1~2. dialogue 10๊ฐœ ์กฐํšŒ ์™„๋ฃŒ

3~4. chat_log ํ•ด์‹œ ์ค€๋น„ ์™„๋ฃŒ

5~6. Hash Join ์‹œ์ž‘ → dialogue์˜ ๊ฐ row์™€ chat_log ๋งค์นญ ์‹œ๋„ → SubPlan 20๋ฒˆ ์‹คํ–‰

```

 

๊ธฐ๋Œ€ํ–ˆ๋˜ ์ฟผ๋ฆฌ๋Š” Join ์ „์— WHERE ์ ˆ์—์„œ ๋ฏธ๋ฆฌ ํ•„ํ„ฐ๋ง๋˜๋Š” ๊ฒƒ์ด์—ˆ์ง€๋งŒ, ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ Hash Join์˜ ์กฐ์ธ ์กฐ๊ฑด์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋ฉด์„œ ๋งค๋ฒˆ ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•ด ๋ถˆํ•„์š”ํ•œ chat_log ์Šค์บ”๊ณผ ์ง‘๊ณ„ ์ž‘์—…์„ 20๋ฒˆ ๋ฐ˜๋ณต ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์ด์ฒ˜๋Ÿผ ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ ๋ฉ”์ธ ์ฟผ๋ฆฌ์˜ d.id๋ฅผ ์ฐธ์กฐํ•˜์—ฌ ๋ฉ”์ธ ์ฟผ๋ฆฌ์— ์˜์กดํ•˜๋Š” ๊ฒƒ์„ ์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ๋Š” ๋ฉ”์ธ ์ฟผ๋ฆฌ์—์„œ ์กฐํšŒ๋œ ๊ฐ ํ–‰๋งˆ๋‹ค ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ต๋‹ˆ๋‹ค.

 

Hash Join ํŠน์ง•

๋˜ํ•œ, Hash Join ์„ ๊ณต๋ถ€ํ•ด๋ณด๋‹ˆ ์‹คํ–‰๊ณ„ํš์— ๋ณด์ธ Hash Join ์ด ์ œ ๊ฒฝ์šฐ์— ์ ํ•ฉํ•œ Join ์ด ์•„๋‹˜์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

Hash Join ์˜ ๋™์ž‘ ์›๋ฆฌ๋Š” 1:N ๊ด€๊ณ„์—์„œ ์ž‘์€ ํ…Œ์ด๋ธ”(1 ํ…Œ์ด๋ธ”)์„ ๋ฉ”๋ชจ๋ฆฌ(PGA ์˜์—ญ, ์„ธ์…˜๋ผ๋ฆฌ ๊ณต์œ ํ•˜์ง€ ์•Š๋Š” ๊ณ ์œ ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ)์— ํ•ด์‹œ ํ…Œ์ด๋ธ”๋กœ ๋นŒ๋“œํ•˜๊ณ , ํฐ ํ…Œ์ด๋ธ”(N ํ…Œ์ด๋ธ”)์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฝ์œผ๋ฉฐ ์กฐ์ธํ•ฉ๋‹ˆ๋‹ค. ํฐ ํ…Œ์ด๋ธ”(N ํ…Œ์ด๋ธ”)์„ ์ˆœ์ฐจ ์ ‘๊ทผํ•˜๊ธฐ ๋•Œ๋ฌธ์— Random Access ๋ถ€ํ•˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

 

์ด ๋•Œ, ํ•ด์‹œ ํ…Œ์ด๋ธ”์„ ๋นŒ๋“œํ•˜๋ฉฐ Join ์ปฌ๋Ÿผ์„ ๊ธฐ์ค€์œผ๋กœ ํ•ด์‹œ ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— Join ์ปฌ๋Ÿผ์ด ์ค‘๋ณต ์—†์ด ๊ณ ์œ ํ•œ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜๋ก ์„ฑ๋Šฅ์— ์ข‹๊ณ , equal join ๋งŒ(๋ฒ”์œ„ Join X) ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์ž‘์€ ํ…Œ์ด๋ธ”์ด ํ•ด์‹œ ์˜์—ญ(๋ฉ”๋ชจ๋ฆฌ)์— ์˜ฌ๋ผ๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ์˜ฌ๋ผ๊ฐ€๋Š” ํ…Œ์ด๋ธ”์˜ ํฌ๊ธฐ๊ฐ€ ์ถฉ๋ถ„ํžˆ ์ž‘์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.(๋ฉ”๋ชจ๋ฆฌ์— Join ์ปฌ๋Ÿผ๋งŒ ์˜ฌ๋ผ๊ฐ€๋ฉด, ํ•ด๋‹น ํ…Œ์ด๋ธ”์˜ ๋‹ค๋ฅธ ์ปฌ๋Ÿผ์˜ ๊ฐ’์„ ์ฝ๊ธฐ ์œ„ํ•ด ๋””์Šคํฌ๋ฅผ ๋‹ค์‹œ ์ฝ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ, ํ•ด์‹œ ์˜์—ญ์—๋Š” Join ์ปฌ๋Ÿผ๋งŒ ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ€๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ, ํ…Œ์ด๋ธ” ์ „์ฒด๊ฐ€ ์˜ฌ๋ผ๊ฐ‘๋‹ˆ๋‹ค). ๋งŒ์•ฝ, ํ…Œ์ด๋ธ”์˜ ํฌ๊ธฐ๊ฐ€ ํ•ด์‹œ ์˜์—ญ์˜ ํฌ๊ธฐ๋ฅผ ๋„˜์–ด๊ฐ€๋ฉด ๋””์Šคํฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์ด๋Ÿฐ ํŠน์ง•์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•ด์‹œ ์กฐ์ธ์˜ ์žฅ์ ์€ ๋ฐฐ์น˜(๋Œ€์šฉ๋Ÿ‰ ํ…Œ์ด๋ธ”)์—์„œ ์“ฐ๋ฉด ์ข‹์€ Join ์ž…๋‹ˆ๋‹ค. ํฐ ํ…Œ์ด๋ธ”(N ํ…Œ์ด๋ธ”)์„ Join ํ•  ๋•Œ, ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ฆฐ ์ž‘์€ ํ…Œ์ด๋ธ”์„ ๋ฐ”ํƒ•์œผ๋กœ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฝ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.  

ํ•ด์‹œ ์กฐ์ธ์˜ ๋‹จ์ ์€ ์‹คํ–‰ ๋นˆ๋„๊ฐ€ ๋†’์€ OLTP ํ™˜๊ฒฝ(์ฃผ๋ฌธ, ์žฌ๊ณ  ์ฒ˜๋ฆฌ, ์ƒํ’ˆ ์กฐํšŒ ๋“ฑ ์งง์€ ํŠธ๋žœ์žญ์…˜)์ž…๋‹ˆ๋‹ค. ์งง์€ ์ฟผ๋ฆฌ๋ฅผ ์œ„ํ•ด ๋งค๋ฒˆ ํ•ด์‹œ ํ…Œ์ด๋ธ”์„ ๋นŒ๋“œํ•ด ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ฆฌ๋Š” ์ผ์€ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ์‹คํ–‰๋นˆ๋„๊ฐ€ ๋†’์€ OLTP ํ™˜๊ฒฝ์ด๋ผ๋ฉด Join ์ด ํ•ด์‹œ ์กฐ์ธ์œผ๋กœ ํ’€๋ฆฌ๊ณ  ์žˆ์ง„ ์•Š์€์ง€ ๊ฒ€ํ† ํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด ํŠน์ง•์„ ๋ฐ”ํƒ•์œผ๋กœ ํฐ ํ…Œ์ด๋ธ”(chat_log)์ด ํ•ด์‹œ ํ…Œ์ด๋ธ”๋กœ ๋นŒ๋“œ ๋œ๋‹ค๋Š” ์ ์—์„œ Join ๋ฐฉ์‹์„ ๋ฐ”๊ฟ€ ํ•„์š”๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.  

 

ํ•ด๊ฒฐ ๋ฐฉ์•ˆ

๋จผ์ €, ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ ๋ฉ”์ธ ์ฟผ๋ฆฌ์— ์˜์กดํ•˜์ง€ ์•Š๋„๋ก ๋…๋ฆฝ์ ์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ์„œ๋ธŒ ์ฟผ๋ฆฌ๊ฐ€ Hash Join ์˜ ์กฐ๊ฑด์œผ๋กœ ์“ฐ์ด์ง€ ์•Š๊ฒŒ ๋˜๋Š” ๊ฒƒ์„ ๊ธฐ๋Œ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

select c.*, d.*
from chat_log c
    join dialogue d
    on c.dialogue_id = d.id
where (d.id, c.seq) IN (
                    select c2.dialogue_id ,min(c2.seq)
                    from lingo_chat_log c2
                    where c2.question <> '' 
                          and c2.dialogue_id IN ('3f056f44-993c-49ce-9c35-8c64821ef270',
                                                 ...
                                                 '53186f20-784a-4f4b-bd0a-1e66061312eb')
                     group by c2.dialogue_id);

 

์ฟผ๋ฆฌ ๋ณ€๊ฒฝ ํ›„ ์‹คํ–‰ ๊ณ„ํš 

๋ณ€๊ฒฝํ•œ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ ๊ณ„ํš์œผ๋กœ ๋ถ„์„ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

๋จผ์ €, ์กฐ์ธ ๋ฐฉ์‹์ด Hash Join์—์„œ Nested Loop Join์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

Nested Loop Join ํŠน์ง•

Nested Loop Join ์˜ ๋™์ž‘ ์›๋ฆฌ๋Š” ์ค‘์ฒฉ for๋ฌธ ์ฒ˜๋Ÿผ 1 : N ํ…Œ์ด๋ธ” ๊ด€๊ณ„์—์„œ outer ํ…Œ์ด๋ธ”(1 ํ…Œ์ด๋ธ”)์˜ ๊ฐ ํ–‰๋งˆ๋‹ค inner ํ…Œ์ด๋ธ”(N ํ…Œ์ด๋ธ”)์„ ํƒ์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

for( i ... outer ) -- 1 ํ…Œ์ด๋ธ”
  for ( j ... inner ) -- N ํ…Œ์ด๋ธ”

 

์ด๋Ÿฐ ๋™์ž‘ ์›๋ฆฌ ๋•Œ๋ฌธ์— Nested Loop Join ์—์„œ inner table ์˜ Join ์ปฌ๋Ÿผ์— ์ธ๋ฑ์Šค๊ฐ€ ๊ฑธ๋ ค์žˆ์ง€ ์•Š์œผ๋ฉด ๋งค์šฐ๋งค์šฐ ๋น„ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.

inner table ์— ์ธ๋ฑ์Šค๊ฐ€ ์—†์œผ๋ฉด outer table ์—์„œ ๊ณ ๋ฅธ 1๊ฐœ์˜ row ๋งˆ๋‹ค inner table ์„ ๋ชจ๋‘ full scan ํ•ด์•ผ ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

 

๋˜ํ•œ, outer ํ…Œ์ด๋ธ”์˜ 1๊ฑด row ๋งˆ๋‹ค inner table์˜ ๋ชจ๋“  ํ–‰์„ ํƒ์ƒ‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€๋Ÿ‰์˜ ํ…Œ์ด๋ธ”์„ Join ํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐ”๋žŒ์ง ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ํŠน์ง• ๋•Œ๋ฌธ์— 1 : N ํ…Œ์ด๋ธ” ๊ด€๊ณ„์—์„œ 1 ์ชฝ์ด outer ํ…Œ์ด๋ธ”๋กœ ๋˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์œผ๋กœ ์„ฑ๋Šฅ์— ์œ ๋ฆฌํ•œ ์ด์œ  ์—ญ์‹œ, outer ํ…Œ์ด๋ธ” ํฌ๊ธฐ๋งŒํผ for๋ฌธ์„ ๋Œ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋งŒ์•ฝ N ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ 10๋งŒ๊ฐœ๋ฉด 10๋งŒ๋ฒˆ์„ ๋„๋Š” ๋ฐ˜๋ฉด, 1 ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ 100๊ฐœ๋ฉด for๋ฌธ์„ 100๋ฒˆ๋งŒ ๋Œ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

 

๋ณธ๋ก ์œผ๋กœ ๋Œ์•„์™€ ๋ฐ”๋€ ์ฟผ๋ฆฌ์˜ ์‹คํ–‰ ๊ณ„ํš์„ ๋ณด๋‹ˆ Nested Loop ์˜ outer table ์ธ chat_log ํ…Œ์ด๋ธ”์ด ํ•„ํ„ฐ๋ง์— ์˜ํ•ด 25๊ฑด(rows=25)์ด ๋‚จ์•„ ์žˆ๊ณ , inner table ์ธ dialogue ํ…Œ์ด๋ธ”์€ pk๋ฅผ ํ™œ์šฉํ•ด ์ธ๋ฑ์Šค ํƒ”์œผ๋ฉฐ, ํšจ์œจ์ ์œผ๋กœ ์Šค์บ” ๋จ์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

์ถ”๊ฐ€ ๊ฐœ์„ ํ•  ์ 

1. ๋ณตํ•ฉ ์ธ๋ฑ์Šค ์„ค์ •

๋จผ์ € ์‹คํ–‰๊ณ„ํš์˜ "Rows Removed by Filter: 4184" ๋ฅผ ํ†ตํ•ด question <> '' ์กฐ๊ฑด๊ณผ dialogue_Id IN (...) ์กฐ๊ฑด ๋•Œ๋ฌธ์— ๋ถˆํ•„์š”ํ•œ 4184๊ฑด์˜ ํ–‰์„ ์ฝ๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ์— question ๊ณผ dialogue_id ์— ๋ณตํ•ฉ ์ธ๋ฑ์Šค๋ฅผ ๊ฑธ๋ฉด ๋ถˆํ•„์š”ํ•œ 4184๊ฑด์˜ ํ–‰์„ ์ฝ์ง€ ์•Š์•„๋„ ๋  ๊ฒƒ์ด๋ผ๋Š” ๊ธฐ๋Œ€๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์นจ, Sort Key ๋กœ dialogue_id ๋ฅผ ์“ฐ๋‹ˆ(๋ณตํ•ฉ ์ธ๋ฑ์Šค ํŠน์„ฑ์ƒ ๋‘ ๋ฒˆ์งธ ์ปฌ๋Ÿผ๋ถ€ํ„ฐ๋Š” ์ง์ „ ์ปฌ๋Ÿผ์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ์ด ๋˜๋‹ˆ), ๋ณตํ•ฉ ์ธ๋ฑ์Šค๋ฅผ (dialouge_id, question)์œผ๋กœ ๊ฑธ๋ฉด Sort(์ •๋ ฌ)๋„ ์‹คํ–‰๊ณ„ํš์—์„œ ๋น ์งˆ ๊ฒƒ ๊ฐ™์€ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

2. PostgreSQL ์˜ partial Index ์„ค์ •

PostgreSQL ์€ partial Index ๋ผ๊ณ  Create Index ๋กœ Index ๋ฅผ ์ƒ์„ฑํ•  ์‹œ, WHERE ์กฐ๊ฑด์— ํ•ด๋‹นํ•˜๋Š” ํ–‰๋งŒ ์ธ๋ฑ์‹ฑ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.(https://www.postgresql.org/docs/current/indexes-partial.html)

์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ธ๋ฑ์Šค ์ €์žฅ ์šฉ๋Ÿ‰์„ ์ค„์ผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ, ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์ถฉ๋ถ„ํ•œ ์„ฑ๋Šฅ์ด ์ด๋ฏธ ๋‚˜์˜ค๊ณ  ์žˆ์—ˆ๊ธฐ์— ํ˜„์žฌ ๋ฌธ์ œ์— ๋งž๋Š” ํ•ด๊ฒฐ์ฑ…๋งŒ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

 

๊ฒฐ๊ณผ

๊ทธ ๊ฒฐ๊ณผ๋กœ ์ธ๋ฑ์Šค ์ถ”๊ฐ€ ์—†์ด ๋ถˆํ•„์š”ํ•œ ์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ, 2.5์ดˆ ๊ฑธ๋ฆฌ๋˜ API ์‘๋‹ต์„ 0.2์ดˆ๋กœ ๊ฐœ์„  ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

์ฐธ๊ณ ์ž๋ฃŒ

- Join ์ˆ˜ํ–‰ ์›๋ฆฌ (https://www.youtube.com/@SQL)

- PostgreSQL Partial Index (https://www.postgresql.org/docs/current/indexes-partial.html)