์ด์ Velog์ ๋์ฉ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์กฐํ ์ฑ๋ฅ์ ๊ฐ์ ํด๋ณด์ (2) : ์ธ๋ฑ์ค ํ๋ (2023.11.12) ๋ก๋ถํฐ ๋ง์ด๊ทธ๋ ์ด์ ๋ ๊ธ์ ๋๋ค.
๋๊ธฐ
1ํธ์ ์นดํ ๊ณ ๋ฆฌ๋ณ ๋ฆฌ๋ทฐ ์กฐํ๋ฅผ ์์์ผ๋ก 500ms๊ฐ ๋์ด๊ฐ๋ ์์ฒญ๋ค์ ์์ฃผ๋ก Cardinality/Selectivity๋ฅผ ๊ณ ๋ คํ์ฌ ์ธ๋ฑ์ค๋ฅผ ์์ฑํ๋ค. ํ์ง๋ง 1ํธ๊น์ง๋ ์ง์ง ๋์ฉ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์๋์๋ค. 2ํธ๋ถํฐ ์ฌ๊ธฐ์ด๋์ปดํผ๋ ๋ฒค์ฒ ํ๋ก์ ํธ์ธ๋งํผ ์ฌ๊ธฐ์ด๋ ํ๋ณด์๋ฃ์ ์๋ ๋ฐ์ดํฐ ๊ท๋ชจ์์ ์ฑ๋ฅ์ ์ธก์ ํด๋ณด๊ณ ํ์ํ๋ค๋ฉด ๊ฐ์ ๊น์ง ์งํํด๋ณด์.
๊ธฐ์กด ํ ์คํธ ๋ฐ์ดํฐ ์ค์ผ์ผ
- ์ฌํ์ํ: 30 (๊ฐ ์นดํ ๊ณ ๋ฆฌ 10๊ฐ์ฉ, ์์, ์๋น, ๋ ํฐ์นด)
- ์์ฝ: 540,000 (์นดํ ๊ณ ๋ฆฌ ๋ณ 180,000)
- ์ฌํ์ํ ๋ง๋ค 18,000๊ฐ์ ์์ฝ- ๋ฆฌ๋ทฐ: 540,000 (์นดํ ๊ณ ๋ฆฌ ๋ณ 180,000)
- ๋ชจ๋ ์์ฝ์ ๋ฆฌ๋ทฐ ์์ฑ- ๋ฆฌ๋ทฐ ํ๊ทธ: 2,700,000 (์นดํ ๊ณ ๋ฆฌ ๋ณ 900,000)
- ๊ฐ ๋ฆฌ๋ทฐ๋น 5๊ฐ์ ๋ฆฌ๋ทฐ ํ๊ทธ
์ฑ๋ฅ ํ ์คํธ
ํ ์คํธ ๋ฐ์ดํฐ ๊ตฌ์ถ
์ฌ๊ธฐ์ด๋ ์ฌ์ดํธ์ ์ํ๋ฉด 600๋ง ๊ฐ ์ด์์ ๋ฆฌ๋ทฐ๋ฅผ ์ ๊ณตํ๊ณ ์๋ค๊ณ ํ๋ค. ์ด์ ๋ง๊ฒ ๋๋ฏธ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํด๋ณด์. 600๋ง ๊ฑด์ ์์ฝ๊ณผ ๋ฆฌ๋ทฐ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ณ ๊ฐ ๋ฆฌ๋ทฐ๋น 3๊ฐ์ ๋ฆฌ๋ทฐ ๋ถ์ ๊ฐ์ด ์๋ค๊ณ ๊ฐ์ ํ์. ์ฌ๊ธฐ์ด๋์ ์ธ๊ธฐ ์์๋ค์ 5000๊ฐ ์ ๋์ ๋ฆฌ๋ทฐ๊ฐ ๋ฌ๋ฆฌ๋ฏ๋ก, ํ ์ํ ๋น 5000๊ฐ๊ฐ ๋ฑ๋ก๋ ์ ์๋๋ก ์ํ์ ๊ฐ์์ ์ฐ๊ด๊ด๊ณ๋ฅผ ์ค์ ํ๋ค.
- ์ฌํ์ํ: 1200
- ์์ฝ: 6,000,000
- ์ฌํ์ํ ๋ง๋ค 5,000๊ฐ์ ์์ฝ - ๋ฆฌ๋ทฐ: 6,000,000
- ๋ชจ๋ ์์ฝ์ ๋ฆฌ๋ทฐ ์์ฑ - ๋ฆฌ๋ทฐ ํ๊ทธ: 18,000,000
- ๊ฐ ๋ฆฌ๋ทฐ๋น 3๊ฐ์ ๋ฆฌ๋ทฐ ํ๊ทธ
์ฑ๋ฅ ์ธก์
์์ฒญ | ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ |
๋ฆฌ๋ทฐ ๋จ์ผ ์กฐํ | 30 ms |
๋ฆฌ๋ทฐ ๋ชฉ๋ก ์กฐํ (LIMIT 10) | 37 ms |
์นดํ ๊ณ ๋ฆฌ ๋ณ ๋ฆฌ๋ทฐ ๋ชฉ๋ก ์กฐํ (LIMIT 10) | 7504 ms |
์นดํ ๊ณ ๋ฆฌ+ํค์๋ ๋ณ ๋ฆฌ๋ทฐ ๋ชฉ๋ก ์กฐํ (LIMIT 10) | 4550 ms |
๋ณ์ ์ ๋ฆฌ๋ทฐ ๋ชฉ๋ก ์กฐํ (LIMIT 10) | 41 ms |
๊ธ์ ์ ์ธ์ ๋ฆฌ๋ทฐ ๋ชฉ๋ก ์กฐํ (LIMIT 10) | 35 ms |
์ํ์ ๋ฆฌ๋ทฐ ํต๊ณ ์กฐํ | 71 ms |
์ํ์ ๋ฆฌ๋ทฐํ๊ทธ ํต๊ณ ์กฐํ | 107 ms |
์ ์์ ์ผ๋ก ์ธ๋ฑ์ค๋ฅผ ํ์ ์ค์ํ ์ฑ๋ฅ์ ๋ณด์ด์ง๋ง, ์ผ๋ถ ๋น์ ์์ ์ธ ์์ฒญ์ด ์๋ค. 1ํธ์์ ์ง์ค์ ์ผ๋ก ๋ค๋ฃฌ ๋ฆฌ๋ทฐ ์์ฑ๊ณผ ํค์๋ ํํฐ๋ง ์กฐํ ์์ฒญ์ด๋ค. ํน์ ํ๊ทธ๋ฅผ ๊ฐ์ง ๋ฆฌ๋ทฐ๋ฅผ ์ ๋ ฌ ๋ฐ ํ์ด์งํด์ผ ํ๋ฏ๋ก, ์ธ๋ฑ์ค๊ฐ ์ ์ฉ๋์ด๋ full scanํด์ผ ํ๋ค. ์๋ ์ํ ๊ณํ์ ๋ณด๋ฉด Full Index Scan์ด ์คํ๋์๊ณ 17802236 rows๊ฐ ์กฐํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | review1_ | null | index | PRIMARY | review_created_at_index | 9 | null | 10 | 100 | null |
1 | SIMPLE | <subquery2> | null | eq_ref | <auto_distinct_key> | <auto_distinct_key> | 8 | Reviewmate.review1_.review_id | 1 | 100 | null |
2 | MATERIALIZED | reviewtag4_ | null | index | review_tag_review_id_property_keyword_index,review_tag_review_id_property_polarity_index | review_tag_review_id_property_polarity_index | 2052 | null | 17902236 | 10 | Using where; Using index |
๊ฐ์
๋ฌธ์ ํ์
select
review1_.review_id as review_i1_8_,
review1_.created_at as created_2_8_,
review1_.updated_at as updated_3_8_,
review1_.content as content4_8_,
review1_.negative_tags_count as negative5_8_,
review1_.polarity as polarity6_8_,
review1_.positive_tags_count as positive7_8_,
review1_.rating as rating8_8_,
review1_.reservation_id as reserva10_8_,
review1_.title as title9_8_
from
review review1_
where
exists (
select
1
from
review_tag reviewtag4_
where
reviewtag4_.review_id=review1_.review_id
and reviewtag4_.property="ROOM"
)
order by
review1_.created_at desc limit 10;
ํ์ฌ ์ ์ฉ๋์ด ์๋ ์ธ๋ฑ์ค๋ 2๊ฐ์ง ์ด๋ค.
- reviewtag index (review_id, property)
- review index (created_at DESC)
where ์ ์์ ์ฌ์ฉ๋๋ ํ ์ด๋ธ๋ค์ ์ธ๋ฑ์ค๋ฅผ ์ ์ฉํ์๊ณ SQL explain์ ํตํด ์ ์์ ์ผ๋ก ์ธ๋ฑ์ค๋ฅผ ํ๊ณ ์์์๋ ๊ธด ์๊ฐ์ด ์๋ชจ๋๋ค. ๋์ ํ ๋ชจ๋ฅด๊ฒ ์ด์ ๋์๋ฆฌ ์ ๋ฐฐ๋๋ค์ด ๋ชจ์ฌ์๋ ์ฌ๋์์ ์กฐ์ธ์ ๊ตฌํด๋ดค๋ค.
๊ทธ๋ ๋ค. ์ค์ ๋ก SQL explain์ ๋ฐ๋ฅด๋ฉด reviewtag scanning rows๋ 17,902,236๋ ๋๋ค. ์ฟผ๋ฆฌ๋ก ์ง์ํ๊ฑด๋ฐ, exists๋ฅผ ํตํด ๋ฆฌ๋ทฐ์ ๋ฌ๋ฆฐ ๋ฆฌ๋ทฐํ๊ทธ ์ค์์ ROOM property๊ฐ ์๋ ๋ฆฌ๋ทฐ๋ฅผ 10๊ฐ ์ฐพ์ ๋๊น์ง ์ ํ์ ์ผ๋ก ํ ์ค์บ์ ํ๊ณ ์๋ ๊ฒ์ด๋ผ๊ณ ์ง์์ด ๋๋ค. ๋ฉ์ธ ์ฟผ๋ฆฌ์ ์ค์บ ๋ฒ์๋ฅผ ์ค์ฌ์ผํ๋๋ฐ 1800๋ง๊ฐ๋ฅผ ์ค์บํ๊ณ ์์ผ๋ฉด ์ค๋ ๊ฑธ๋ฆด ์ ๋ฐ์ ์์ ๊ฒ์ด๋ค.
์ตํฐ๋ง์ด์ ๋ SQL์ ์ต๋ํ ํจ์จ์ ์ผ๋ก ๋์ํ๊ธฐ ์ํด ๋ค์ํ ์ต์ ํ๋ฅผ ์๋์ผ๋ก ์ ์ฉํ๋ค๊ณ ์๊ณ ์๋๋ฐ, ์ ๋ง ๋ฐฉ๋ฒ์ด ์๋ ๊ฒ์ผ๊น? ์ฟผ๋ฆฌ์ ์คํ ๊ณํ์ ๋ ์์ธํ ์์๋๋ฐ, ์์๊ฐ ์์๊ณผ๋ ์กฐ๊ธ ๋ฌ๋๋ค. ํ๋ํ๋ ์กฐ์ฌํด๋ณด์.
explain analysis graph
1. property filter
์ฐ์ ์ ์ฒด ๋ฆฌ๋ทฐํ๊ทธ ์ค์์ property ์ปฌ๋ผ์ด ROOM์ธ ๊ฒ๋ง ํํฐ๋งํ๋ค.
2. deduplication
๋ฆฌ๋ทฐ์๋ 3๊ฐ์ ๋ฆฌ๋ทฐํ๊ทธ๊ฐ ์ฐ๊ด๋๋ฏ๋ก, ์ค๋ณต๋๋ ํ๊ทธ๋ค์ ์ ๊ฑฐํ๋ deduplication ๊ณผ์ ์ ๊ฑฐ์น๋ค. ๋ค์ด์ด๊ทธ๋จ์ ์ ํ์๋ rows๋ ํต๊ณ๋ฅผ ํตํ ์ถ์ฒญ์น์ด๊ณ , ์ค์ ๋ก propert๊ฐ ROOM ํ๊ทธ๋ง ๊ณจ๋๋ค๋ฉด 800,000 ์ ๋ ๋๋ค.
Materialize๋ MySQL์ด ์๋ธ์ฟผ๋ฆฌ๋ ๋ณต์กํ ์กฐ์ธ์ ์ฒ๋ฆฌํ ๋, ์ค๊ฐ ๊ฒฐ๊ณผ๋ฅผ ์์ ํ ์ด๋ธ์ ์ ์ฅํ๋ ๊ณผ์ ์ ๋งํ๋ค. ๋์ฑ ํจ์จ์ ์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ ์ ์๊ณ ๋ฐ๋ณต์ ์ธ ๊ณ์ฐ์ ์ค์ผ ์ ์๋ค.
3. FK๋ฅผ ํตํ Nested loop inner join
ํํฐ๋ง๊ณผ ์ค๋ณต์ด ์ ๊ฑฐ๋ ๋ฆฌ๋ทฐ ํ๊ทธ๋ฅผ review์ join์ ํตํด ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ค.
4. LIMIT, SELECT
๋ฌผ๋ก MySQL ๋ด๋ถ์ ์ผ๋ก ์ ์ต์ ํ๋์ด 800000๊ฐ ์ ๋ถ Joinํ์ง๋ ์๊ณ ํ์ํ 10๊ฐ๋ง Join ํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ์ ๊ฒ์ด๋ค.
์ต์ ํ
์ด์ํ๋ค.. ๋๋ ๋ถ๋ช reviewtag4_.review_id=review1_.review_id and reviewtag4_.property="ROOM" ๋ก where ์ ์ ์์ฑํ์ผ๋ฏ๋ก ์ธ๋ฑ์ค๋ ์ด ์์๋ก ์ ์ฉํ์๋ค. ํ์ง๋ง ์ค์ ์คํ ์์๋ฅผ ๋ฐ๋์๋ค. ์๋ง๋, 1:N ๊ด๊ณ์ธ ๋ฆฌ๋ทฐ์ ๋ฆฌ๋ทฐํ๊ทธ ๊ด๊ณ ์, ๋ฆฌ๋ทฐ์ ๊ด๊ณ๋ ๋ฆฌ๋ทฐํ๊ทธ๋ฅผ ๋ถ๋ฌ์์ property๋ฅผ ํ์ธํ๋ ๊ฒ๋ณด๋ค property๋ฅผ ์ถฉ์กฑํ๋ ๋ฆฌ๋ทฐํ๊ทธ์ ์ค๋ณต์ ์ ๊ฑฐํ๊ณ ๋ฆฌ๋ทฐ์ ์ฐ๊ด์ํค๋๊ฒ ํจ์จ์ ์ด๋ผ๊ณ ํ๋จํ ๊ฒ ๊ฐ๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด ์์์ ๋ง๊ฒ ์ธ๋ฑ์ค๋ฅผ ์ ์ฉํด๋ณด๋ฉด ์ด๋จ๊น? ๊ฒฐ๊ณผ๋ ์ฑ๊ณต์ ์ด๋ค!
- reviewtag index (property, review_id)
explain analysis graph
property filter์ deduplication์ด ํ ๋จ๊ณ๋ก ํฉ์ณ์ก๋ค. ์ด์ ์๋ ์์๊ฐ ๋ง์ง ์์ property filter ์ดํ review_id๋ฅผ ํตํ deduplicationdl ๋ถ๊ฐ๋ฅํ์ง๋ง, ์ด์ ๋ covering index๋ก ํ ๋ฒ์ ๊ฐ๋ฅํ์ฌ ๋ ๋จ๊ณ๊ฐ ํตํฉ๋ ๊ฒ ๊ฐ๋ค. ๋จ์ ์ผ๋ก ์์น๋ง ๋น๊ตํ์๋ฉด 100๋ง ๊ฑด ์ด์์ ์ค์บ์ด ์๋ต๋ ๊ฒ์ด๋ค. ๊ทธ ๊ฒฐ๊ณผ ์ฟผ๋ฆฌ ์คํ์๊ฐ๋ 7.5์ด์์ 1.5์ด๋ก ๋จ์ถ๋์๋ค.
explain analysis
-> Limit: 10 row(s) (cost=2.05e+6 rows=10) (actual time=1552..1552 rows=10 loops=1)
-> Nested loop inner join (cost=2.05e+6 rows=14.5e+6) (actual time=1552..1552 rows=10 loops=1)
-> Index scan on review1_ using review_created_at_index (cost=0.0707 rows=10) (actual time=0.0462..0.0762 rows=14 loops=1)
-> Single-row index lookup on <subquery2> using <auto_distinct_key> (review_id=review1_.review_id) (cost=466650..466650 rows=1) (actual time=111..111 rows=0.714 loops=14)
-> Materialize with deduplication (cost=466649..466649 rows=1.45e+6) (actual time=1552..1552 rows=800000 loops=1)
-> Covering index lookup on reviewtag4_ using review_tag_property_review_id_index (property='ROOM') (cost=321768 rows=1.45e+6) (actual time=0.0266..323 rows=800000 loops=1)
์ค์ ์ค์ผ์ผ ์ ์ฉ
์์ง ๋น ๋๋ฆฐ ๊ฒ์ด ์๋ค. ์ฑ๋ฅ ์ ํ๊ฐ ๋ฐ์ํ๋ ๋ฆฌ๋ทฐ ํ๊ทธ ๋ถ๋ถ์ด ์ถ๊ฐ๋ ์ฟผ๋ฆฌ๋ง ๋ค๋ค๋๋ฐ, ์ด์ ๋ ์ํ์ด ์์๋ ์ฌํ์ฌ์ ๋ฆฌ๋ทฐ๊ฐ ์์๋ ์ํ์ ๋น๊ตํ๋ ์กฐ๊ฑด์ ๋ ์ถ๊ฐ๋์ด์ผ ํ๋ค. ์ด์ ๋ง๊ฒ ์ธ๋ฑ์ค๋ ์ ๋ํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
์คํ์๊ฐ๋ 1500 ms -> 120 ms๋ก ๋ํญ ๊ฐ์๋์๋๋ฐ, ์ด์ ๊น์ง๋ 2400๋ง ๊ฐ(๋ฆฌ๋ทฐ 600๋ง + ๋ฆฌ๋ทฐํ๊ทธ 1200๋ง)๋ฅผ ๋์์ผ๋ก ์กฐํํ๋ค๋ฉด ํ์ฌ๋ 2๋ง ๊ฐ(๋ฆฌ๋ทฐ 5000 + ๋ฆฌ๋ทฐํ๊ทธ 10000)๋ฅผ ๋์์ผ๋ก ์กฐํํ๊ณ ์๋ค. ๋ฐ๋ผ์ ์ฑ๋ฅ ์ ํ๊ฐ ๋ฐ์ํ๋ ๋ฆฌ๋ทฐ์ ๋ฆฌ๋ทฐํ๊ทธ์ ๊ฐ์๊ฐ ์ค์ด๋ค์ด scanning rows ์์ฒด๊ฐ ์ค์ด๋ค์ด์์ด๋ค.
๋ง๋ฌด๋ฆฌ
๊ธด ์๊ฐ ๋์ ์ ๋ง์ ์๋์ ์ฐฉ์ค์ ๋์ 2400๋ง ๊ฐ์ ๋ฐ์ดํฐ(๋ฆฌ๋ทฐ 600๋ง + ๋ฆฌ๋ทฐํ๊ทธ 1200๋ง)๋ฅผ ๋์์ผ๋ก 94%์ ์ฑ๋ฅ ๊ฐ์ ์ ์ด๋ค๋ด ๋งค์ฐ ๋ง์กฑ์ค๋ฌ์ด ๊ฒฐ๊ณผ๋ก ๋ง๋ฌด๋ฆฌ๋์๋ค. ๊ฐ์ฅ ํฌ๊ฒ ๋ฐฐ์ด ๊ฒ์ ์ฟผ๋ฆฌ ์คํ ๊ณํ ๋ถ์๋ฒ๊ณผ ์ธ๋ฑ์ค ์์ฑ ์ ๋ต์ธ ๊ฒ ๊ฐ๋ค. ์ฒ์ ์ธ๋ฑ์ค๋ฅผ ๋ฐฐ์ฐ๋ฉด์ ๋ถ์์ ํ๊ฒ ๋ฐฐ์ด ์ด๋ก ๋ง์ ๋ฐํ์ผ๋ก ์ต์ ํํ๋ค๋ณด๋ ๋ง์ ์ํ์ฐฉ์ค๋ฅผ ๊ฒช์์ง๋ง, ๊ทธ ๊ณผ์ ์์ ์ค์ ๋์ํ๋ DB ์์ง๊ณผ ์ตํฐ๋ง์ด์ ์ ๋์์ ๋ง๊ฒ ์ธ๋ฑ์ค๋ฅผ ํ๋ํด๋๊ฐ๋ ๋ฒ์ ๋ฐฐ์ธ ์ ์์๋ค. ํนํ, "์ธ๋ฑ์ค์ ์์๊ฐ ๋ง์ง ์์ผ๋ฉด ์ ๋๋ก ์ธ๋ฑ์ค๋ฅผ ์ ๋๋ก ํ์ง ์๋ ๊ฒ"๊ณผ "์ธ๋ฑ์ค๋ฅผ ์ ๋๋ก ํ์ง ์๋ ๊ฒ"์ ์ง์ ํ ์๋ฏธ๋ฅผ ๊ฒฝํํ ์ ์์๋ค. ๊ฐ๋ณ๊ฒ ์ด๋ก ์ ๋ฐฐ์ฐ๊ณ ์ธ๋ฑ์ค๋ฅผ ํตํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ์ง์ ๋ถ๋ชํ๋ณด๋ฉฐ ๋ง์ ๊ฒ์ ๋ฐฐ์ ์ผ๋, ์ด ๊ฒฝํ์ ๋ฐํ์ผ๋ก ๋ ๊น์ ์ด๋ก ๋ ๋ฐฐ์๋ณผ๊น ํ๋ค.
์ฑ๋ฅ ๊ฐ์ ๊ฒฐ๊ณผ
์์ฒญ๊ธฐ์กด ์กฐํ ์๊ฐ์ ์ฒด ๋ฆฌ๋ทฐ ๋์ ์กฐํ ์๊ฐ์ํ ๋ฆฌ๋ทฐ ๋์ ์กฐํ ์๊ฐ
๋ฆฌ๋ทฐ ๋จ์ผ ์กฐํ | 30 ms | 33 ms | 32 ms |
๋ฆฌ๋ทฐ ๋ชฉ๋ก ์กฐํ (LIMIT 10) | 37 ms | 35 ms | 113 ms |
์นดํ ๊ณ ๋ฆฌ ๋ณ ๋ฆฌ๋ทฐ ๋ชฉ๋ก ์กฐํ (LIMIT 10) | 7504 ms | 1555 ms | 132 ms |
์นดํ ๊ณ ๋ฆฌ+ํค์๋ ๋ณ ๋ฆฌ๋ทฐ ๋ชฉ๋ก ์กฐํ (LIMIT 10) | 4550 ms | 10 ms | 11 ms |
๋ณ์ ์ ๋ฆฌ๋ทฐ ๋ชฉ๋ก ์กฐํ (LIMIT 10) | 41 ms | 36 ms | 89 ms |
๊ธ์ ์ ์ธ์ ๋ฆฌ๋ทฐ ๋ชฉ๋ก ์กฐํ (LIMIT 10) | 35 ms | 33 ms | 76 ms |
์ํ์ ๋ฆฌ๋ทฐ ํต๊ณ ์กฐํ | 71 ms | 70 ms | 40 ms |
์ํ์ ๋ฆฌ๋ทฐํ๊ทธ ํต๊ณ ์กฐํ | 107 ms | 188 ms | 176 ms |
๊ธฐ์กด ๋๋น ๊ฐ์ ์จ | 84 % | 94 % |
๋ค์ํ ์ํ์ฐฉ์ค๋ค
1. Join์ผ๋ก Exists ์๋ธ ์ฟผ๋ฆฌ ๋์ฒด
QueryDSL any() ๊ฐ ์๋ ์์ฑํ where(exist(select 1 ~))) ๋ฅผ ์ฌ์ฉํ๊ณ ์์ง๋ง, reviewtag scan rows๊ฐ ๊ต์ฅํ ํฐ ๊ฒ์ผ๋ก ๋ณด์ ์ธ๋ฑ์ค๋ฅผ ์ ๋๋ก ํ์ง ์๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค. ์๋ธ์ฟผ๋ฆฌ ๊ตฌ์กฐ์ ํ๊ณ์ผ ์ ์๋ค๊ณ ์๊ฐ๋์ด, ์๋ธ์ฟผ๋ฆฌ ๋์ join์ ์ด์ฉํด๋ณด์.
select
distinct review0_.review_id as review_i1_8_,
review0_.created_at as created_2_8_,
review0_.updated_at as updated_3_8_,
review0_.content as content4_8_,
review0_.negative_tags_count as negative5_8_,
review0_.polarity as polarity6_8_,
review0_.positive_tags_count as positive7_8_,
review0_.rating as rating8_8_,
review0_.reservation_id as reserva10_8_,
review0_.title as title9_8_
from
review review0_
inner join
review_tag reviewtags1_
on review0_.review_id=reviewtags1_.review_id
where
reviewtags1_.property="ROOM"
order by
review0_.created_at desc limit 10;
14์ด ์ ๋๋ก ์คํ๋ ค ์ฑ๋ฅ์ด ์ ํ๋์๋ค. ํนํ ๋ฆฌ๋ทฐํ๊ทธ ๋น๊ต๊ฐ ๋ค์ด๊ฐ์ง ์์ ๊ต์ฅํ ๋น ๋ฅด๋ ๊ฐ๋จํ ์กฐํ๋ค์ด 40์ด ๋๊ฒ ๊ฑธ๋ฆฌ๋ ๋ฑ์ ๋ชจ์ต์ ๋ณด์๋ค.
2. ์ธ๋ฑ์ค ์ฃผ์
๊ธฐ์กด์ Exists ๋ฐฉ์์ where ์ ๋ด๋ถ์์ reviewtag์ review_id์ property๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ์ธ๋ฑ์ค๋ reviewtag index(review_id, property, keyword)๋ฅผ ์ฐ๊ณ ์์๋ค. ํ์ง๋ง Join ๋ฐฉ์ ์ฟผ๋ฆฌ์ where์ ์์ ๋์ด์ review_id๋ฅผ ์ฌ์ฉํ์ง ์์์๋ ์ธ๋ฑ์ค๋ ์ ์์ ์ผ๋ก ํ์ง๋๋ฐ, ์ฟผ๋ฆฌ ์คํ์๊ฐ์ ๋งค์ฐ ๊ธธ์ด์ก๋ค.
ํ์ง๋ง ์ธ๋ฑ์ค๋ฅผ reviewtag index(property, keyword)๋ก ์ ์์ ์ผ๋ก ๋ณ๊ฒฝํ๋ฉด, ๋ง์ฐฌ๊ฐ์ง๋ก ๋ณ๊ฒฝ๋ ์ธ๋ฑ์ค๋ก ํ์ง๋ฉฐ ์คํ์๊ฐ๋ ๊ต์ฅํ ์งง์์ง๋ค. ์คํ๊ณํ์ผ๋ก ๋น๊ตํ๋ฉด reviewtag์ scan ๋จ๊ณ์์ actual rows: 18e+6 -> 800,000๋ก ๋ํญ ๊ฐ์ํ์ผ๋ฉฐ Filter ๋จ๊ณ๊ฐ ์๋ต๋๋ค. ๊ธฐ์กด์ ์ธ๋ฑ์ค๋ review_id ์ฒ์์ ์๋ ํ์ ํ์ค์บ์ฒ๋ผ ๋์ํ์๊ณ , ์ดํ ์ธ๋ฑ์ค๋ ์ ์์ ์ผ๋ก ์ปค๋ฒ๋ง ์ธ๋ฑ์ค๋ก ๋์ํ์๋ค.
์๋ง, ์ตํฐ๋ง์ด์ ๊ฐ ๋นํจ์จ์ ์ธ ์ธ๋ฑ์ค VS ํ์ค์บ์ ๋น๊ตํ์ ๋, ๊ทธ๋๋ ๋นํจ์จ์ ์ธ ์ธ๋ฑ์ค๊ฐ ๋ ํจ์จ์ ์ด๋ผ ์ธ๋ฑ์ค๋ฅผ ํ ๊ฒ ๊ฐ๋ค. ์ธ๋ฑ์ค์ ์์์ ์ด ๋ค๋ฅด๋ฉด ์ธ๋ฑ์ค๊ฐ ํ์ง์ง ์๋๋ค๋ ์ด๋ก ์ ์ธ ๋ฐฐ์์๋ง ์์กดํด์ key ๋ถ๋ถ๋ง ๋น๊ตํ๋๋ฐ, ๋์ฑ ๋ฉด๋ฐํ ์ดํด๋ณด๋ฉฐ ์ฃผ์ํด์ผํ ๊ฒ ๊ฐ๋ค.
3. Distinct VS Group by
Review 1 : Reviewtag N ๊ด๊ณ์ด๋ฏ๋ก, ์ค๋ณต๋๋ ๋ฆฌ๋ทฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด deduplication ๊ณผ์ ์ด ํ์ํ๋ค. ๋ฌธ๋ฒ์ ์ผ๋ก ๊ฐ์ฅ ๋ชฉ์ ์๋ ๋ง๊ณ ์ผ๋ฐ์ ์ผ๋ก ๋ ๋น ๋ฅธ distinct๋ฅผ ์ฐ๊ณ ์์๋๋ฐ, Join ๋ฐฉ์์ ์ฟผ๋ฆฌ์์๋ ์ง์ ์๋ํด๋ณด๋ ๋ฌ๋๋ค.
distinct ์คํ๊ณํ
-> Temporary table with deduplication (cost=2.4e+6..2.4e+6 rows=1.62e+6) (actual time=13088..13088 rows=800000 loops=1)
group by ์คํ๊ณํ
-> Temporary table with deduplication (cost=2.4e+6..2.4e+6 rows=1.62e+6) (actual time=8587..8587 rows=800000 loops=1)
๊ด๋ จ๋ ์๋ฃ๋ฅผ ์๋ฌด๋ฆฌ ์กฐ์ฌํด๋ ์ผ๋ฐ์ ์ผ๋ก๋ distinct๊ฐ ๋น ๋ฅด๋ค๋ ์๋ฃ ๋ฐ์ ์ฐพ์ ์ ์์๋ค. ์คํ ๊ณํ ์ cost๋ ๊ฐ์์๋ actual time์ด ์ฐจ์ด๊ฐ ๋๋ค. ์ผ๋จ์ ๋ ๋น ๋ฅธ group by๋ฅผ ์ฑ์ฉํ์๋ค. ์คํ ์๊ฐ์ 8์ด ์ ๋์๋ค.