์ฟผ๋ฆฌ ํ๋์ ํตํด ํผ๋ ๊ฐ์ ํ๊ธฐ
- #์ฟผ๋ฆฌ ํ๋
- #์ฑ๋ฅ ๊ฐ์
- #typeORM
- #DB
- #sql
๋ค์ด๊ฐ๋ฉฐ
์๋ ํ์ธ์, ๋ ธ๋จธ์ค ๋ฐฑ์๋ํ์ ํฉ๋ฅํ ์๋ํ์ ๋๋ค.
๋ ธ๋จธ์ค๋ fromm์ด๋ผ๋ ์ํต ์ฑ์ ์๋น์คํ๊ณ ์์ต๋๋ค. ๊ทธ ์ค ์ฑ๋์ด๋ผ๋ ์๋น์ค๊ฐ ์๋๋ฐ, ์ฑ๋์ ์ํฐ์คํธ์ ํฌ๋ค์ด ๊ฒ์๊ธ๊ณผ ๋๊ธ์ ํตํด ์ํตํ๋ฉฐ, ๋ผ์ด๋ธ, ๊ณต์ง์ฌํญ, ๋ค์๋ณด๊ธฐ ๋ฑ ํด๋น ์ํฐ์คํธ๊ฐ ์์๋ ๊ทธ๋ฃน์ ์ ๋ณด๋ฅผ ๋ณผ ์ ์๋ ๊ณต๊ฐ์ ๋๋ค.

์ฒซ ์ ๋ฌด๋ก ๋ถํํ ์คํธ๋ฅผ ์งํํ๋ฉด์ ์ฑ๋์์ ๋์ ๋ถํ์ latency๊ฐ ๋ฐ์ํ๋ค๋ ๊ฒ์ ํ์ ํ๊ณ , ์ด์ ๋ฌธ์ ์ ์์ธ์ ๋ถ์ํ๊ณ ๊ฐ์ ํ๊ธฐ๋ก ํ์ต๋๋ค.
๋ฌธ์ ๋ถ์
RDS์๋ ์ฑ๋ฅ ๊ฐ์ ๋์ฐ๋ฏธ๋ผ๋ ๊ธฐ๋ฅ์ด ์์ด ๋ถํ๋ฅผ ๋ง์ด ์ฐจ์งํ๋ ์ฟผ๋ฆฌ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
์ด ๋๊ตฌ๋ฅผ ํตํด ๋ถ์ํ ๊ฒฐ๊ณผ, ๋ฌธ์ ๊ฐ ๋๋ ์ฟผ๋ฆฌ๋ ํฌ ํผ๋๋ฅผ ๋ถ๋ฌ์ค๋ ์ฟผ๋ฆฌ์์ต๋๋ค. ๋ค์ํ ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ์ด ์ถ๊ฐ๋๋ฉด์ ํฌ ํผ๋ ์กฐํ ์ฟผ๋ฆฌ์ ์ฌ๋ฌ ๊ด๊ณ(relation)๊ฐ ์ถ๊ฐ๋์ด ๋ถํ๊ฐ ๋ฐ์ํ ๊ฒ์ ๋๋ค.

๊ฐ๋ฐ ๊ณผ์ ์์ ๊ธฐ์กด ๊ธฐํ์ ์๋ ์๊ตฌ์ฌํญ์ด๋ ์ถ๊ฐ ๊ธฐํ์ด ๋ง๋ฌผ๋ ค ๊ธฐ์กด API์ ์ฑ๋ฅ์ด ์ ํ๋๋ ๊ฒฝ์ฐ๋ฅผ ์์ฃผ ๋ณผ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ํฉ์์ ๊ธฐ์กด ๋น์ฆ๋์ค ๋ก์ง์ ์ ์งํ๋ฉด์ ์ฟผ๋ฆฌ ํ๋์ ํตํด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ
1๋จ๊ณ: ์ธ๋ฑ์ค ๊ฒ์ฆ
์ฒซ ๋ฒ์งธ๋ก ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ํ๋ ๋ฐฉ๋ฒ์ ์ธ๋ฑ์ค ํ์ฉ ์ฌ๋ถ๋ฅผ ๊ฒ์ฆํ๋ ๊ฒ์ ๋๋ค.
์ด๋ค ์ธ๋ฑ์ค๊ฐ ์กด์ฌํ๋์ง ํ์ ํด์ผ ์ฟผ๋ฆฌ์ ๋ง์ถฐ ์ต์ ํ๊ฐ ๋๊ณ ์๋์ง ์ ์ ์๊ธฐ ๋๋ฌธ์ ์ธ๋ฑ์ค ํ์ธ์ ์ค์ํฉ๋๋ค. ์ธ๋ฑ์ค๋ฅผ ํ์ฉํ๊ณ ์์์๋ ์ฟผ๋ฆฌ ์ฑ๋ฅ์ ๋ถํ๊ฐ ๊ฑธ๋ฆฐ๋ค๋ฉด ์ฟผ๋ฆฌ๋ฅผ ๋ถํ ํ๊ฑฐ๋ ๋ฐฉ์์ ๋ณ๊ฒฝํ๋ ์กฐ์น๊ฐ ํ์ํ๋ฏ๋ก, EXPLAIN ANALYZE ๋ช ๋ น์ด๋ฅผ ํตํด ์ฟผ๋ฆฌ์ ์คํ ๊ณํ์ ํ์ ํ๋ ๊ฒ์ด ์ธ๋ฑ์ค ๊ฒ์ฆ์ ์ฒซ ๋จ๊ณ์ ๋๋ค.
EXPLAIN ANALYZE ์ฌ์ฉ ์๋๋ฆฌ์ค
- ์ฟผ๋ฆฌ ์ฑ๋ฅ์ด ๋๋ ค์ง ์ด์ ๋ฅผ ์ฐพ์ ๋
- ์ธ๋ฑ์ค๊ฐ ์ ๋๋ก ํ์ฉ๋๋์ง ํ์ธํ ๋
- JOIN ์ต์ ํ๊ฐ ํ์ํ์ง ํ๋จํ ๋
EXPLAIN ANALYZE๋ฅผ ํตํด ์ฟผ๋ฆฌ๋ฅผ ํ์ธํ ๊ฒฐ๊ณผ, ์ ์ ํ ์ธ๋ฑ์ค๋ฅผ ํ์ฉํ์ง ์๊ณ ์์์ต๋๋ค. ํ ์ด๋ธ์ ์ธ๋ฑ์ค๋ฅผ ํ์ธํ ๊ฒฐ๊ณผ ์ ์ ํ ์ธ๋ฑ์ค๊ฐ ์ค์ ๋์ด ์์ง ์๋ค๋ ๊ฒ์ ํ์ ํ๊ณ , ์ฑ๋ฅ ๊ฐ์ ์ ์ํ ์ฒดํฌ๋ฆฌ์คํธ๋ฅผ ์์ฑํ์ต๋๋ค.
๊ฐ์ ์ฒดํฌ๋ฆฌ์คํธ
- ์ต์ ํ๋ ์ธ๋ฑ์ค ์ถ๊ฐ
- ๋น์ฆ๋์ค ๋ก์ง ํ์ธ
- ์ฟผ๋ฆฌ ๊ตฌ์กฐ ๊ฐ์
- ๋ถํ๋ฅผ ์ผ์ผํฌ ์ ์๋ ์๋น์ค ๊ตฌ์กฐ ์ฒดํฌ
2๋จ๊ณ: ์ฟผ๋ฆฌ ๊ตฌ์กฐ ๋ถ์
ํด๋น ์ฟผ๋ฆฌ๊ฐ ์์นํ ์ฝ๋๋ฅผ ๋ถ์ํ ๊ฒฐ๊ณผ, TypeORM์ ์ฌ์ฉํ๋ ๋ฐฑ์๋์์ ๋จ์ ํ์ธ ๋ก์ง์ด JOIN์ ๋ก ๊ตฌ์ฑ๋์ด ์์์ต๋๋ค.
๋ฌธ์ ๊ฐ ๋๋ ์ฟผ๋ฆฌ๋ฅผ ์์ธํ ์กฐ์ฌํด๋ณด๋, ์ฒ์์๋ ์์ฒญํ ๊ฒ์๋ฌผ์ ๊ฐ์ ธ์ฌ ๋ ์ ์ ์ ์ ๊ณ ๋ฐ์ดํฐ๋ฅผ LEFT JOINํด์ reportedPost.id IS NULL ์กฐ๊ฑด์ ๊ฑฐ๋ ๋ถ๋ถ์ด ์์์ต๋๋ค. ์ด ๋ถ๋ถ์ด ์ฑ๋ฅ ๋ถํ์ ์ฃผ์ ์์ธ์ผ๋ก ์ถ์ธก๋์์ต๋๋ค.
-- ๊ธฐ์กด ์ฟผ๋ฆฌ (๋ฌธ์ ๊ฐ ๋๋ ๋ถ๋ถ)
SELECT feedPost.*
FROM feed_posts feedPost
LEFT JOIN reported_feed_posts reportedPost
ON feedPost.id = reportedPost.post_id
AND reportedPost.user_id = ?
AND reportedPost.active = true
WHERE feedPost.channel_id = ?
AND feedPost.active = true
AND reportedPost.id IS NULL -- ์ด ๋ถ๋ถ์ด ์ฑ๋ฅ ์ด์ ๋ฐ์
ORDER BY feedPost.created_at DESC
์ฟผ๋ฆฌ ํ๋ ์์น
์ฟผ๋ฆฌ ํ๋์๋ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ณธ ์์น๋ค์ด ์์ต๋๋ค:
- ์ข๋ณ ๊ฐ๊ณต ๊ธ์ง: WHERE์ ์์ ์ปฌ๋ผ์ ํจ์๋ก ๊ฐ๊ณตํ์ง ์๊ธฐ
- ์ ์ ํ ์กฐ์ธ ๋ฐฉ์ ์ ํ: ๋จ์ ํ์ธ์ฉ์ด๋ผ๋ฉด JOIN < IN < EXISTS ์์ผ๋ก ์ฑ๋ฅ ์ ๋ฆฌ
- NULL ์ฒ๋ฆฌ: NULL ๊ฐ์ ๋ํ ์ ์ ํ ์ฒ๋ฆฌ
- ์กฐ์ธ ์์ ์ต์ ํ: INNER JOIN ์ ์์ ํ ์ด๋ธ๋ถํฐ ์ฐ์ฐ
- ๋ช ์์ Alias ์์ฑ: ์ค๋ณต์ ๋ฐฉ์งํ๊ณ ๊ฐ๋ ์ฑ ํฅ์
- UNION ํ์ฉ: ๋ณต์กํ WHERE์ ๋์ UNION ์ฌ์ฉ ๊ณ ๋ ค
- VIEW ํ์ฉ: ๋ณต์กํ ์ฐ์ฐ์ ๊ฒฝ์ฐ VIEW๋ฅผ ํตํ ๋จ์ํ
์ 2๋ฒ ์์น์ ์ ์ฉํ๋๊ฐ?
๊ธฐ์กด ์ฟผ๋ฆฌ์์ LEFT JOIN + IS NULL ํจํด์ **โ์ ๊ณ ๋์ง ์์ ๊ฒ์๋ฌผ๋ง ๊ฐ์ ธ์ค๊ธฐโ**๋ผ๋ ๋จ์ํ ํ์ธ ๋ก์ง์ด์์ต๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ JOIN๋ณด๋ค๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ํจ์จ์ ์
๋๋ค:
- JOIN ๋ฐฉ์์ ๋ฌธ์ ์ : ๋ชจ๋ ๊ฒ์๋ฌผ์ ๋ํด ์ ๊ณ ํ ์ด๋ธ๊ณผ ์กฐ์ธ ํ NULL ์ฒดํฌ
- ์๋ธ์ฟผ๋ฆฌ ๋ฐฉ์์ ์ฅ์ : ์ ๊ณ ๋ ๊ฒ์๋ฌผ ID๋ง ๋จผ์ ์ถ์ถ ํ ์ ์ธํ๋ ๋ฐฉ์์ผ๋ก ๋ ์ง๊ด์ ์ด๊ณ ๋น ๋ฆ
๋ฐ๋ผ์ 2๋ฒ ์์น์ ๋ฐ๋ผ JOIN์ ์ NOT IN ์๋ธ์ฟผ๋ฆฌ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝํ์ฌ ์ฟผ๋ฆฌ๋ฅผ ๊ฐ์ ํ๊ธฐ๋ก ํ์ต๋๋ค.
๊ธฐ์ ์ ๊ณ ๋ ค์ฌํญ
์๋๋ EXISTS์ ์ ์ฌ์ฉํ๋ ค ํ์ผ๋, ํ ์คํธ ํ๊ฒฝ์ ์ ์ฝ์ผ๋ก NOT IN์ ์ ์ ํํ์ต๋๋ค. ์ค์ ํ๋ก๋์ ์์๋ ๋ค์๊ณผ ๊ฐ์ ์ฐจ์ด์ ์ด ์์ต๋๋ค:
- EXISTS: NULL ๊ฐ ์ฒ๋ฆฌ์ ์์ ํ๊ณ , ๋์ฉ๋ ๋ฐ์ดํฐ์์ ์ผ๋ฐ์ ์ผ๋ก ๋ ๋น ๋ฆ
- NOT IN: NULL ๊ฐ์ด ์์ผ๋ฉด ์์์น ๋ชปํ ๊ฒฐ๊ณผ ๋ฐ์ ๊ฐ๋ฅ, ํ์ง๋ง ์์ ๋ฐ์ดํฐ์ ์์๋ ์ถฉ๋ถํ ํจ์จ์
์ ์ฝ์ฌํญ๊ณผ ํธ๋ ์ด๋์คํ
๋ฐฑ์๋ ํ์ ํ ์คํธ ์ฝ๋๋ฅผ ์ค์ํ๋ฉฐ ๋ชจ๋ ์๋น์ค์ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค. ํ์ฌ pg-mem์ ํตํด ๊ฐ๋ณ๊ณ ๋น ๋ฅธ ํ ์คํธ ๊ตฌ์กฐ๋ฅผ ๊ตฌ์ถํ๊ณ ์์๋๋ฐ, pg-mem์ ํ๊ณ๋ก EXISTS์ ์ ํด์ํ์ง ๋ชปํ๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค.
์ด๋ก ์ธํด ๋ ๊ฐ์ง ์ ํ์ง๊ฐ ์์์ต๋๋ค:
- ํ ์คํธ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ๊ณ EXISTS์ ์ ์ฌ์ฉํ์ฌ ์ต์ ํ
- ์ฑ๋ฅ์ ์ฝ๊ฐ์ ์ํด๋ฅผ ๊ฐ์ํ๊ณ NOT IN์ ๋ก ๊ฐ์
์์ฌ๊ฒฐ์ ๊ณผ์
๊ฐ๋ฐ์์ ์ค์ํ ๊ฒ์ ๊ธฐ์ ์ ์๋ฒฝํจ๊ณผ ๋น์ฆ๋์ค ํจ์จ์ฑ ์ฌ์ด์ ๊ท ํ์ ๋๋ค. ๋จ์ํ ์๊ตฌ์ฌํญ๋ง ๊ตฌํํ๋ ๊ฒ์ด ์๋๋ผ, ํด๋น ๊ธฐ๋ฅ์ ์ฃ์ง ์ผ์ด์ค์ ๊ฐ๋ฐ ๋ฐฉํฅ์ฑ์ ๋น์ฉ ์ธก๋ฉด์์ ํจ์จ์ ์ผ๋ก ํ๋จํด์ผ ํฉ๋๋ค.
NOT IN์ ๋ณ๊ฒฝ๊ณผ ์ธ๋ฑ์ค ์ถ๊ฐ์ ๋นํด ํ ์คํธ ๊ตฌ์กฐ ๋ณ๊ฒฝ์ ์๋นํ ๊ณต์๊ฐ ํ์ํ๋ฏ๋ก, NOT IN์ ๊ณผ ์ธ๋ฑ์ค ์ถ๊ฐ ๋ฐฉ์์ผ๋ก ๊ฐ์ ํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
๊ตฌํ ๊ณผ์
๋ชฉ์ ์ด ์ ํด์ง๋ฉด ๊ฐ์ ๊ณผ์ ์ ๋ช ํํฉ๋๋ค:
- ์ฟผ๋ฆฌ ๊ตฌ์กฐ ๊ฐ์
- ๊ฐ์ ๋ ์ฟผ๋ฆฌ์ ๋ง๋ ์ธ๋ฑ์ค ์ถ๊ฐ
๋จผ์ ์ฟผ๋ฆฌ๋ฅผ ๊ฐ์ ํ๊ณ , ๊ฐ์ ๋ ์ฟผ๋ฆฌ์ ๋ง์ถฐ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๋ ์์๋ก ์งํํ์ต๋๋ค. ์ด๋ฅผ ์ํด ๊ธฐ์กด ์ธ๋ฑ์ค ํํฉ์ ํ์ ํ๊ณ , ์ด๋ค ๋ฐฉ์์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ๊ฐ์ ํ ์ง ๊ณํ์ ์ธ์ ์ต๋๋ค.
์๋ธ์ฟผ๋ฆฌ ํ์ฉ ๋ฐฉ์
NOT IN์ ์ ํ์ฉํ๋ ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์๋ธ์ฟผ๋ฆฌ๋ฅผ ํตํด ํํฐ๋งํ ๋ฐ์ดํฐ๋ฅผ ๋จผ์ ์ถ์ถ
- ๋ฉ์ธ ์ฟผ๋ฆฌ์ SELECT๋ฅผ ๋จ์ํํ์ฌ ์ฑ๋ฅ ํฅ์
๊ฐ์ ์ ์ฟผ๋ฆฌ (JOIN ๋ฐฉ์)
// ๊ธฐ์กด JOIN ๋ฐฉ์ - ์ฑ๋ฅ ์ด์ ๋ฐ์
const feedPosts = await this.dataSource
.getRepository(FeedPost)
.createQueryBuilder("feedPost")
.leftJoin(
"feedPost.reportedPosts",
"reportedPost",
"reportedPost.user_id = :userId AND reportedPost.active = :active"
)
.where("feedPost.channel_id = :channelId")
.andWhere("feedPost.active = :active")
.andWhere("reportedPost.id IS NULL") // ์ ๊ณ ๋์ง ์์ ๊ฒ์๋ฌผ๋ง
.orderBy("feedPost.created_at", "DESC")
.limit(20)
.getMany();
๊ฐ์ ํ ์ฟผ๋ฆฌ (์๋ธ์ฟผ๋ฆฌ ๋ฐฉ์)
// ๊ฐ์ ๋ NOT IN ์๋ธ์ฟผ๋ฆฌ ๋ฐฉ์
const reportedPostIdsSubQuery = this.dataSource
.getRepository(ReportedFeedPost)
.createQueryBuilder("reportedFeedPost")
.select("reportedFeedPost.post_id")
.where(`reportedFeedPost.user_id = :userId`)
.andWhere("reportedFeedPost.active = :active");
const feedPosts = await this.dataSource
.getRepository(FeedPost)
.createQueryBuilder("feedPost")
.where("feedPost.channel_id = :channelId")
.andWhere("feedPost.active = :active")
.andWhere(`feedPost.id NOT IN (${reportedPostIdsSubQuery.getQuery()})`)
.orderBy("feedPost.created_at", "DESC")
.limit(20)
.setParameters({ channelId, userId, active: true })
.getMany();
์ฐธ๊ณ : NULL ๊ฐ ์ฒ๋ฆฌ
// ์ผ๋ฐ์ ์ผ๋ก NOT IN ์ฌ์ฉ ์ NULL ์์ ์ฑ์ ์ํ ์ถ๊ฐ ์กฐ๊ฑด์ด ํ์ํ์ง๋ง
// ์ด ๊ฒฝ์ฐ post_id๊ฐ FeedPost.id๋ฅผ ์ฐธ์กฐํ๋ FK์ด๋ฏ๋ก NULL ๊ฐ์ด ์์ด ์๋ต ๊ฐ๋ฅ
.andWhere(`feedPost.id NOT IN (${reportedPostIdsSubQuery.getQuery()})`)
// ๋ง์ฝ FK ์ ์ฝ์ด ์๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด NULL ์ฒ๋ฆฌ ํ์:
// .andWhere(`feedPost.id NOT IN (${reportedPostIdsSubQuery.getQuery()})
// OR (${reportedPostIdsSubQuery.getQuery()}) IS NULL`)
์ธ๋ฑ์ค ์ต์ ํ
๊ฐ์ ๋ ์ฟผ๋ฆฌ์ ๋ง์ถฐ ๋ค์ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ์ต๋๋ค:
์ถ๊ฐ๋ ์ธ๋ฑ์ค
-- FeedPost ํ
์ด๋ธ ๋ณตํฉ ์ธ๋ฑ์ค
CREATE INDEX CONCURRENTLY idx_feedpost_channel_active_created
ON feed_posts (channel_id, active, created_at DESC);
์ธ๋ฑ์ค ์ค๊ณ ๊ณ ๋ ค์ฌํญ
- CONCURRENTLY ์ต์ : ์๋น์ค ์ค๋จ ์์ด ์ธ๋ฑ์ค ์์ฑ
- ์ปฌ๋ผ ์์: WHERE์ ์์ ๊ฐ์ฅ ์ ํ์ ์ธ ์ปฌ๋ผ์ ์์ ๋ฐฐ์น
- DESC ์ ๋ ฌ: ์ต์ ๊ฒ์๋ฌผ ์กฐํ ํจํด์ ๋ง์ถฐ created_at์ ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ค์
์ฑ๋ฅ ๊ฐ์ ๊ฒฐ๊ณผ
์๋ต ์๊ฐ ๊ฐ์
๊ฐ์ ์
๊ฐ์ ํ
๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ถํ ๊ฐ์

์ค์ธก ์ฑ๋ฅ ๊ฐ์ ๊ฒฐ๊ณผ
์ฟผ๋ฆฌ ๊ตฌ์กฐ ๊ฐ์ ๊ณผ ์ธ๋ฑ์ค ์ถ๊ฐ๋ฅผ ํตํด ์ค์ ์ธก์ ๋ ์ฑ๋ฅ ํฅ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์๋ต ์๊ฐ: ํ๊ท 6.3์ด โ 0.4์ด (์ฝ 94% ๊ฐ์ )
- CPU ์ฌ์ฉ๋ฅ : ํ๊ท 75% โ 5% (์ฝ 93% ๊ฐ์)
์ด๋ฌํ ๊ฐ์ ์ ํตํด ์ฌ์ฉ์๋ค์ด ํผ๋๋ฅผ ํจ์ฌ ๋น ๋ฅด๊ฒ ๋ก๋ฉํ ์ ์๊ฒ ๋์๊ณ , ์๋ฒ ๋ฆฌ์์ค ์ฌ์ฉ๋๋ ํฌ๊ฒ ์ค์ด๋ค์์ต๋๋ค. ๊ฐ์ ์ ํ ๋น๊ต ์์๊ณผ RDS ๋ถํ ๊ทธ๋ํ์์ ํ์ธํ ์ ์๋ฏ์ด ์๋นํ ์ฑ๋ฅ ํฅ์์ ๋ฌ์ฑํ์ต๋๋ค.
๊ฒฝํ์ ํตํด ์ป์ ๊ตํ
์ด๋ฒ ์ฟผ๋ฆฌ ํ๋ ์์ ์ ํตํด ๋ช ๊ฐ์ง ์ค์ํ ์ธ์ฌ์ดํธ๋ฅผ ์ป์์ต๋๋ค:
- ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง์ ์ค์์ฑ: RDS ์ฑ๋ฅ ๊ฐ์ ๋์ฐ๋ฏธ ๊ฐ์ ๋๊ตฌ๋ฅผ ํ์ฉํ ์ง์์ ์ธ ๋ชจ๋ํฐ๋ง์ด ๋ฌธ์ ๋ฅผ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌํ๋ ํต์ฌ
- ํ์ค์ ์ ๊ทผ์ ๊ฐ์น: ๊ธฐ์ ์ ์๋ฒฝํจ๋ณด๋ค๋ ํ์ค์ ์ด๊ณ ์คํ ๊ฐ๋ฅํ ๊ฐ์ ์ด ๋ ํฐ ๊ฐ์น๋ฅผ ์ฐฝ์ถ
- ์ฒด๊ณ์ ๋ฌธ์ ํด๊ฒฐ: ์ธ๋ฑ์ค ๊ฒ์ฆ โ ์ฟผ๋ฆฌ ๋ถ์ โ ๊ตฌ์กฐ ๊ฐ์ โ ์ฑ๋ฅ ์ธก์ ์ ๋จ๊ณ์ ์ ๊ทผ์ด ํจ๊ณผ์
- ์ ์ฝ์ฌํญ ์ธ์ : ํ ์คํธ ํ๊ฒฝ์ ํ๊ณ ๊ฐ์ ์ค๋ฌด์ ์ ์ฝ์ ์ธ์ ํ๊ณ ์ต์ ์ ๋์ ์ ํ
์ฟผ๋ฆฌ ํ๋ ์ ์ฃผ์์ฌํญ
์ธ๋ฑ์ค ์ถ๊ฐ ์ ๊ณ ๋ คํ ์
์ธ๋ฑ์ค๋ ์กฐํ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํค์ง๋ง, ๋ช ๊ฐ์ง ํธ๋ ์ด๋์คํ๊ฐ ์์ต๋๋ค:
- ์ฐ๊ธฐ ์ฑ๋ฅ ์ํฅ: ์๋ก์ด ๋ฐ์ดํฐ๊ฐ ์ถ๊ฐ๋๊ฑฐ๋ ์์ ๋ ๋๋ง๋ค ์ธ๋ฑ์ค๋ ํจ๊ป ์ ๋ฐ์ดํธ๋์ด์ผ ํ๋ฏ๋ก INSERT/UPDATE ์ฑ๋ฅ์ด ์ ํ๋ ์ ์์ต๋๋ค
- ์คํ ๋ฆฌ์ง ์ฌ์ฉ๋: ๋ณตํฉ ์ธ๋ฑ์ค๋ ์ถ๊ฐ์ ์ธ ๋์คํฌ ๊ณต๊ฐ์ ์ฐจ์งํ๋ฏ๋ก ์คํ ๋ฆฌ์ง ๋น์ฉ์ด ์ฆ๊ฐํฉ๋๋ค
- ์ ์ง๋ณด์ ๋น์ฉ: ์ธ๋ฑ์ค๊ฐ ๋ง์์ง์๋ก ๊ด๋ฆฌ ํฌ์ธํธ๊ฐ ๋์ด๋๊ณ , ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง์ด ๋ณต์กํด์ง๋๋ค
NOT IN vs EXISTS ์ ํ ๊ธฐ์ค
์ด๋ฒ ํ๋ก์ ํธ์์ EXISTS ๋์ NOT IN์ ์ ํํ์ง๋ง, ์ผ๋ฐ์ ์ธ ์ ํ ๊ธฐ์ค์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
-- ์์ ์๋ธ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ์
(< 1000๊ฑด): NOT IN ์ฌ์ฉ ๊ฐ๋ฅ
-- ํฐ ์๋ธ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ์
(> 1000๊ฑด): EXISTS ๊ถ์ฅ
-- NULL ๊ฐ ๊ฐ๋ฅ์ฑ: ํญ์ EXISTS ์ฌ์ฉ ๊ถ์ฅ
ํนํ NOT IN์ ์๋ธ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ์ NULL์ด ํฌํจ๋๋ฉด ์์์น ๋ชปํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ ์ ์์ผ๋ฏ๋ก ์ฃผ์๊ฐ ํ์ํฉ๋๋ค. ๋ค๋ง ์ด๋ฒ ๊ฒฝ์ฐ์ฒ๋ผ FK ์ ์ฝ์กฐ๊ฑด์ด ์์ด NULL ๊ฐ์ด ๋ณด์ฅ๋์ง ์๋๋ค๋ฉด ์ถ๊ฐ ์ฒ๋ฆฌ ์์ด ์ฌ์ฉํด๋ ์์ ํฉ๋๋ค.
์ฑ๋ฅ ํ๋ ์ ๊ทผ ์์
๊ฒฝํ์ ๋ค์ ์์๋ก ์ ๊ทผํ๋ ๊ฒ์ด ํจ๊ณผ์ ์ ๋๋ค:
- ์ธ๋ฑ์ค ์ต์ ํ: ๊ฐ์ฅ ์ ์ ๋น์ฉ์ผ๋ก ํฐ ํจ๊ณผ๋ฅผ ์ป์ ์ ์๋ ๋ฐฉ๋ฒ์ ๋๋ค. ๊ธฐ์กด ์ฟผ๋ฆฌ๋ฅผ ๊ฑฐ์ ์์ ํ์ง ์๊ณ ๋ ์ฑ๋ฅ ํฅ์์ด ๊ฐ๋ฅํฉ๋๋ค
- ์ฟผ๋ฆฌ ๊ตฌ์กฐ ๊ฐ์ : ์ค๊ฐ ์ ๋์ ํจ๊ณผ๋ฅผ ๊ธฐ๋ํ ์ ์์ง๋ง, ์ฝ๋ ์์ ๊ณผ ํ ์คํธ๊ฐ ํ์ํฉ๋๋ค
- ์บ์ฑ ๋์ : ๋์ ์ฑ๋ฅ ํฅ์์ ๊ธฐ๋ํ ์ ์์ง๋ง, ์บ์ ๋ฌดํจํ ์ ๋ต ๋ฑ ๋ณต์ก์ฑ์ด ์ฆ๊ฐํฉ๋๋ค
- ํ๋์จ์ด ์ ๊ทธ๋ ์ด๋: ์ฆ์ ํจ๊ณผ๋ฅผ ๋ณผ ์ ์์ง๋ง ๋น์ฉ์ด ๊ฐ์ฅ ๋๊ณ , ๊ทผ๋ณธ์ ์ธ ํด๊ฒฐ์ฑ ์ ์๋๋๋ค
๋ง๋ฌด๋ฆฌํ๋ฉฐ
๊ฐ๋ฐ ๊ณผ์ ์์ ํ๋์ API์ ๋ค์ํ ์๊ตฌ์ฌํญ์ด ์ถ๊ฐ๋๋ฉด์ ์์์น ๋ชปํ ์ฑ๋ฅ ์ด์๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ๊ฐ๋ฐ์๋ ์์ ์ด ์์ฑํ ์ฝ๋์ ๋ํด ์ง์์ ์ผ๋ก ๊ฒํ ํ๊ณ ๊ฐ์ ํด ๋๊ฐ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
fromm ์ฌ์ฉ์๋ค์ด ๋ ๋น ๋ฅด๊ณ ์์ ์ ์ธ ์๋น์ค๋ฅผ ์ด์ฉํ ์ ์๋๋ก ์ง์์ ์ธ ์ฑ๋ฅ ๊ฐ์ ์ ๋ ธ๋ ฅํ๊ฒ ์ต๋๋ค.
๊ฐ์ฌํฉ๋๋ค!