๐Ÿค– Backend/Database

๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์กฐํšŒ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•ด๋ณด์ž (1) : ์ธ๋ฑ์Šค ์ ์šฉ

sckwon770 2024. 2. 25. 19:06

์ด์ „ Velog์˜ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์กฐํšŒ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•ด๋ณด์ž (1) : ์ธ๋ฑ์Šค ์ ์šฉ (2023.10.27) ๋กœ๋ถ€ํ„ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๋œ ๊ธ€์ž…๋‹ˆ๋‹ค.

Github main repo / Github server repo

 

 


๋™๊ธฐ

์ง€๋‚œ ๋ฒˆ์— ๋‹ค์–‘ํ•œ JPA ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๋น„ํšจ์œจ์ ์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ตœ์ ํ™”ํ•ด ์ „์ฒด์ ์ธ ์„œ๋ฒ„ ์„ฑ๋Šฅ์ด ๋Œ€ํญ ํ–ฅ์ƒ๋˜์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฆฌ๋ทฐ ์กฐํšŒ API์˜ ์ผ๋ถ€ ์š”์ฒญ์˜ ๊ฒฝ์šฐ ๋Œ€ํญ ํ–ฅ์ƒ๋˜์—ˆ์Œ์—๋„ ๋งŒ์กฑ์Šค๋Ÿฌ์šด ์ฟผ๋ฆฌ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์— ๋„๋‹ฌํ•˜์ง€ ๋ชปํ–ˆ๋‹ค. ๋‹ค์–‘ํ•œ ์ •๋ ฌ๊ณผ ํ•„ํ„ฐ๋ง์„ ์ง€์›ํ•˜๋Š” ์กฐํšŒ ์ฟผ๋ฆฌ์ธ๋งŒํผ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ๊ฑด์ ˆ, ์ •๋ ฌ ์ ์šฉํ•˜๋Š”๋ฐ ๋งŽ์€ ๋น„์šฉ์ด ๋“ค๊ณ , ํŠนํžˆ ๋ฆฌ๋ทฐ์˜ ๋ถ„์„ ๊ฒฐ๊ณผ ์ค‘ '์ฒญ๊ฒฐ' ์†์„ฑ์ด ํฌํ•จ๋œ ๋ฆฌ๋ทฐ๋“ค์ด๋‚˜ ๋ฆฌ๋ทฐ์˜ ๋ถ„์„ ๊ฒฐ๊ณผ ์ค‘ '์ฒญ๊ฒฐ' ์†์„ฑ์˜ '๋จผ์ง€' ํ‚ค์›Œ๋“œ๊ฐ€ ํฌํ•จ๋œ ๋ฆฌ๋ทฐ๋“ค๊ณผ ๊ฐ™์ด review ํ…Œ์ด๋ธ”๊ณผ ์—ฐ๊ด€๋˜์—ˆ์œผ๋ฉด์„œ ๊ฐ€์žฅ ๋งŽ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์ ์žฌ๋œ review_tag ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜๋Š” ์ฟผ๋ฆฌ๋“ค์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์กด์žฌํ•˜๋Š” ํด๋Ÿฌ์Šคํ„ฐ๋ง ์ธ๋ฑ์Šค์™€ ์™ธ๋ž˜ํ‚ค ์ธ๋ฑ์Šค๋กœ๋Š” ์ธ๋ฑ์Šค๋ฅผ ํƒ€์ง€ ์•Š์•„ ๋‹ค๋ฅธ ์ฟผ๋ฆฌ ๋Œ€๋น„ 80๋ฐฐ ์ •๋„ ๋” ๊ธด ์š”์ฒญ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ์†Œ์š”๋˜์—ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ์ฟผ๋ฆฌ๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ํ”„๋กœํŒŒ์ผ๋งํ•ด๋ณด๋ฉฐ ์ˆ˜์ •ํ•˜๊ณ  ์ธ๋ฑ์Šค๋ฅผ ์ ์šฉํ•ด ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•ด๋ณด์ž.

 

์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ

๋Œ€์‹œ๋ณด๋“œ API ์„ฑ๋Šฅ์„ ์ธก์ •ํ•˜๋Š” ๊ณผ์ •์—์„œ ์—ฐ๋‹จ์œ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์„ฑ๋Šฅ์„ ๋‹ค์‹œ ์ธก์ •ํ•ด์•ผํ•œ๋‹ค. ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ์น˜๊ณ ๋Š” ์กฐ๊ธˆ ๋งŽ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์žˆ์ง€๋งŒ ๋ฆฌ๋ทฐ 54๋งŒ ๊ฐœ๋Š” ํ”„๋กœ๋•์…˜์—์„œ ์ƒ์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์Šค์ผ€์ผ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ

  • ์—ฌํ–‰์ƒํ’ˆ: 30 (๊ฐ ์นดํ…Œ๊ณ ๋ฆฌ 10๊ฐœ์”ฉ, ์ˆ™์†Œ, ์‹๋‹น, ๋ Œํ„ฐ์นด)
  • ์˜ˆ์•ฝ: 540,000 (์นดํ…Œ๊ณ ๋ฆฌ ๋ณ„ 180,000)
    • ์—ฌํ–‰์ƒํ’ˆ ๋งˆ๋‹ค 18,000๊ฐœ์˜ ์˜ˆ์•ฝ
  • ๋ฆฌ๋ทฐ: 540,000 (์นดํ…Œ๊ณ ๋ฆฌ ๋ณ„ 180,000)
    • ๋ชจ๋“  ์˜ˆ์•ฝ์— ๋ฆฌ๋ทฐ ์ž‘์„ฑ
  • ๋ฆฌ๋ทฐ ํƒœ๊ทธ: 2,700,000 (์นดํ…Œ๊ณ ๋ฆฌ ๋ณ„ 900,000)
    • ๊ฐ ๋ฆฌ๋ทฐ๋‹น 5๊ฐœ์˜ ๋ฆฌ๋ทฐ ํƒœ๊ทธ

ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ

์ฒซ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ์— ๋น„ํ•ด 4๋ฐฐ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ์š”์ฒญ์ด ์ •ํ™•ํžˆ 4๋ฐฐ์˜ ์‹œ๊ฐ„์ด ์†Œ์š”๋˜์—ˆ๋‹ค. ์ธ๋ฑ์Šค๋ฅผ ํƒ€์ง€ ์•Š๊ณ  Full Table Scanํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๊ฐ„์ ‘์ ์œผ๋กœ๋„ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ํŠนํžˆ, 2543 ms, 7147 ms๋Š” ๋น„์ •์ƒ์ ์ธ๋ฐ, ํ•ด๋‹น ์š”์ฒญ๋“ค์ด ๋ฆฌ๋ทฐ ํƒœ๊ทธ์˜ ์†์„ฑ๊ณผ ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด ํ•„ํ„ฐ๋งํ•˜๋Š” ์š”์ฒญ์ด๋‹ค. ๊ทธ๋Ÿผ ํ•ด๋‹น ์š”์ฒญ๋“ค์„ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์ตœ์ ํ™”ํ•ด๋ณด์ž.

2023-10-27 04:19:58.851  INFO 99446 --- [    Test worker] PERFORMANCE                              : ===== ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ์‹œ์ž‘ =====
2023-10-27 04:19:58.851  INFO 99446 --- [    Test worker] PERFORMANCE                              : (4/5) ๋ฆฌ๋ทฐ API
2023-10-27 04:19:59.152  INFO 99446 --- [o-auto-1-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-10-27 04:19:59.152  INFO 99446 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-10-27 04:19:59.152  INFO 99446 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
2023-10-27 04:20:01.909  WARN 99446 --- [o-auto-1-exec-1] PERFORMANCE                              : uri: '/api/widget/v1/goodchoice.kr/products/123/reviews', method: 'GET', ์š”์ฒญ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„: 2741.021375 ms, ์ฟผ๋ฆฌ ๊ฐœ์ˆ˜: 14, ์ฟผ๋ฆฌ ์‹œ๊ฐ„: 2543.819333 ms
2023-10-27 04:20:09.110  WARN 99446 --- [o-auto-1-exec-2] PERFORMANCE                              : uri: '/api/widget/v1/goodchoice.kr/products/123/reviews', method: 'GET', ์š”์ฒญ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„: 7177.475416 ms, ์ฟผ๋ฆฌ ๊ฐœ์ˆ˜: 14, ์ฟผ๋ฆฌ ์‹œ๊ฐ„: 7147.840791 ms
2023-10-27 04:20:09.152  WARN 99446 --- [o-auto-1-exec-3] PERFORMANCE                              : uri: '/api/widget/v1/goodchoice.kr/products/123/reviews', method: 'GET', ์š”์ฒญ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„: 31.841500 ms, ์ฟผ๋ฆฌ ๊ฐœ์ˆ˜: 14, ์ฟผ๋ฆฌ ์‹œ๊ฐ„: 18.417707 ms
2023-10-27 04:20:09.492  WARN 99446 --- [o-auto-1-exec-4] PERFORMANCE                              : uri: '/api/widget/v1/goodchoice.kr/products/123/reviews', method: 'GET', ์š”์ฒญ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„: 332.011875 ms, ์ฟผ๋ฆฌ ๊ฐœ์ˆ˜: 14, ์ฟผ๋ฆฌ ์‹œ๊ฐ„: 314.414834 ms
2023-10-27 04:20:09.638  WARN 99446 --- [o-auto-1-exec-5] PERFORMANCE                              : uri: '/api/widget/v1/goodchoice.kr/products/4e16aa67-a2fd-4c92-ad11-775a3ad190e4/statistics/reviews', method: 'GET', ์š”์ฒญ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„: 139.288167 ms, ์ฟผ๋ฆฌ ๊ฐœ์ˆ˜: 2, ์ฟผ๋ฆฌ ์‹œ๊ฐ„: 112.839875 ms
2023-10-27 04:20:10.348  WARN 99446 --- [o-auto-1-exec-6] PERFORMANCE                              : uri: '/api/widget/v1/goodchoice.kr/products/4e16aa67-a2fd-4c92-ad11-775a3ad190e4/statistics/tags', method: 'GET', ์š”์ฒญ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„: 701.198125 ms, ์ฟผ๋ฆฌ ๊ฐœ์ˆ˜: 2, ์ฟผ๋ฆฌ ์‹œ๊ฐ„: 689.250418 ms

 

 


์ตœ์ ํ™”

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

๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ํ•ด๋‹น ์š”์ฒญ์€ "goodchoice.kr" ๋„๋ฉ”์ธ์— id๊ฐ€ 123์ธ ์—ฌํ–‰ ์ƒํ’ˆ์— ๋“ฑ๋ก๋œ ๋ฆฌ๋ทฐ ์ค‘ ์ฒญ๊ฒฐ(CLEANNESS) ํƒœ๊ทธ๋ฅผ ๊ฐ€์ง„ ๋ฆฌ๋ทฐ๋“ค์„ 10๊ฐœ ์กฐํšŒํ•˜๋Š” ์š”์ฒญ์ด๋‹ค.

GET /api/widget/v1/goodchoice.kr/products/123/reviews 
{"property": "CLEANNESS"}

๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฟผ๋ฆฌ๋“ค๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

 

1. ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” review๋“ค์„ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ

2์ดˆ ๊ฐ€๋Ÿ‰ ๊ฑธ๋ฆฌ๋Š” ์š”์ฒญ์—์„œ 1683ms๊ฐ€ ์†Œ์š”๋˜๋Š” ์ฟผ๋ฆฌ๋กœ์„œ, ์„ฑ๋Šฅ ์ €ํ•˜์˜ ์ฃผ์š” ์›์ธ์ด ๋˜๋Š” ์ฟผ๋ฆฌ์ด๋‹ค. ํŠนํžˆ ๋ฆฌ๋ทฐ์— ํฌํ•จ๋œ ํƒœ๊ทธ๋“ค ์ค‘ ํ•˜๋‚˜๋ผ๋„ CLEANNESS๊ฐ€ ํฌํ•จ๋˜์—ˆ๋‹ค๋ฉด ์กฐํšŒ๋ผ๋Š” ์ฟผ๋ฆฌ๋ฅผ QueryDSL any()๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„ํ•˜์˜€๋Š”๋ฐ ์„œ๋ธŒ์ฟผ๋ฆฌ๋กœ์„œ ์‹คํ–‰๋œ๋‹ค. ์ฟผ๋ฆฌ ์‹คํ–‰ ๊ณ„ํš์„ ๋ณด๋ฉด <subquery2>์™€ reviewtags3_์ด ์ธ๋ฑ์Šค๋„ ์—†์ด ์—„์ฒญ๋‚œ ์–‘์˜ rows๋ฅผ ๋‹ค๋ฃจ๊ณ  ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๋ถ€๋ถ„์ด ์ตœ์ ํ™” ํฌ์ธํŠธ 1์ด๋‹ค.

select
        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_.title as title9_8_ 
    from
        review review0_ 
    where
        exists (
            select
                1 
            from
                review_tag reviewtags3_ 
            where
                review0_.review_id=reviewtags3_.review_id 
                and reviewtags3_.property=?
        ) 
    order by
        review0_.created_at desc limit ?

10 rows retrieved starting from 1 in 1 s 683 ms (execution: 1 s 667 ms, fetching: 16 ms)

 

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE review0_ null ALL PRIMARY null null null 448427 100 Using filesort
1 SIMPLE <subquery2> null eq_ref <auto_distinct_key> <auto_distinct_key> 8 reviewmate.review0_.review_id 1 100 null
2 MATERIALIZED reviewtags3_ null ALL FKea2voymuynf2rmdx7ph30cwoe null null null 2177808 10 Using where

 

2. ๋ฆฌ๋ทฐ์˜ ์ž‘์„ฑ์ž ์ด๋ฆ„์„ ์œ„ํ•ด ์—ฐ๊ด€๋œ reservation, customer ํ…Œ์ด๋ธ”์„ ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰ํ•˜๋Š” ์ฟผ๋ฆฌ

review ํ…Œ์ด๋ธ”์— ์ง€์—ฐ ๋กœ๋”ฉ๋˜์ง€๋งŒ ์ž‘์„ฑ์ž์˜ ์ด๋ฆ„์„ ์•Œ๊ธฐ ์œ„ํ•ด 2๊ฐœ์˜ ํ…Œ์ด๋ธ”์„ ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด (๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜ * 2) ๋งŒํผ์˜ ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒ๋˜๊ณ  ์žˆ๋‹ค. ํ•˜์ง€๋งŒ review ํ…Œ์ด๋ธ”์— ์ž‘์„ฑ์ž ์ด๋ฆ„์„ ๋น„์ •๊ทœํ™”ํ•˜์ง€ ์•Š๋Š” ์ด์ƒ ๋ถˆ๊ฐ€ํ”ผํ•œ ํƒ์ƒ‰์ด๋ฉฐ, ๋ณธ ํฌ์ŠคํŒ…๊ณผ ๋ฌด๊ด€ํ•˜์ง€๋งŒ fetch join์„ ํ†ตํ•ด ์ฟผ๋ฆฌ ๊ฐœ์ˆ˜๋ฅผ ์ค„์ด๋Š” ์‹œ๋„๋„ ํ•˜์˜€์ง€๋งŒ, reservation๊ณผ customer์— ์žˆ๋Š” ๋งŽ์€ ์ปฌ๋Ÿผ๋“ค์ด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์กฐํšŒ๋˜๋Š” ๊ฒƒ์ด ์˜คํžˆ๋ ค ๋งŽ์€ ์‹œ๊ฐ„์ผ ์†Œ๋ชจ์‹œ์ผฐ๋‹ค. ์ด ์ฟผ๋ฆฌ๋“ค์€ ์‹œ๊ฐ„๋„ 134 ms๋กœ ์ค€์ˆ˜ํ•˜๋ฏ€๋กœ, ๋„˜์–ด๊ฐ€๋„๋ก ํ•˜์ž.

select
        reservatio0_.reservation_id as reservat1_7_0_,
        reservatio0_.created_at as created_2_7_0_,
        reservatio0_.updated_at as updated_3_7_0_,
        reservatio0_.customer_id as customer7_7_0_,
        reservatio0_.end_date_time as end_date4_7_0_,
        reservatio0_.live_feedback_id as live_fee8_7_0_,
        reservatio0_.live_satisfaction_id as live_sat9_7_0_,
        reservatio0_.partner_custom_id as partner_5_7_0_,
        reservatio0_.review_id as review_10_7_0_,
        reservatio0_.start_date_time as start_da6_7_0_,
        reservatio0_.travel_product_id as travel_11_7_0_ 
    from
        reservation reservatio0_ 
    where
        reservatio0_.review_id=?
-- X 10
select
        customer0_.customer_id as customer1_0_0_,
        customer0_.created_at as created_2_0_0_,
        customer0_.updated_at as updated_3_0_0_,
        customer0_.kakao_id as kakao_id4_0_0_,
        customer0_.name as name5_0_0_,
        customer0_.partner_company_id as partner_8_0_0_,
        customer0_.partner_custom_id as partner_6_0_0_,
        customer0_.phone_number as phone_nu7_0_0_ 
    from
        customer customer0_ 
    where
        customer0_.customer_id in (
            ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
        )

10 rows retrieved starting from 1 in 134 ms (execution: 111 ms, fetching: 23 ms)

 

3. Pagination์˜ totalCount๋ฅผ ์œ„ํ•ด ์กฐ๊ฑด์— ๋งŒ์กฑํ•˜๋Š” review๋“ค์„ ์นด์šดํŒ…ํ•˜๋Š” ์ฟผ๋ฆฌ

IN ์ฟผ๋ฆฌ๋กœ ์ž˜ ์ตœ์ ํ™”๋˜์–ด ์žˆ๋‹ค.

select
        count(review0_.review_id) as col_0_0_ 
    from
        review review0_ 
    where
        review0_.review_id in (
            ? , ? , ? , ? , ? , ? , ? , ? , ? , ?
        )

 

4. ์กฐํšŒ๋œ review์™€ ์—ฐ๊ด€๋œ review_tag๋“ค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•œ ์ถ”๊ฐ€ ์ฟผ๋ฆฌ

response DTO๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •์—์„œ ์š”์ฒญ๋˜๋Š” ์ถ”๊ฐ€ ์กฐํšŒ ์ฟผ๋ฆฌ์ง€๋งŒ, ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ IN ์ฟผ๋ฆฌ๋กœ ์ž˜ ์ตœ์ ํ™”๋˜์–ด ์žˆ๋‹ค.

select
        reviewtags0_.review_id as review_i9_10_1_,
        reviewtags0_.review_tag_id as review_t1_10_1_,
        reviewtags0_.review_tag_id as review_t1_10_0_,
        reviewtags0_.created_at as created_2_10_0_,
        reviewtags0_.updated_at as updated_3_10_0_,
        reviewtags0_.end_index as end_inde4_10_0_,
        reviewtags0_.keyword as keyword5_10_0_,
        reviewtags0_.polarity as polarity6_10_0_,
        reviewtags0_.review_id as review_i9_10_0_,
        reviewtags0_.property as property7_10_0_,
        reviewtags0_.start_index as start_in8_10_0_ 
    from
        review_tag reviewtags0_ 
    where
        reviewtags0_.review_id in (
            ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
        )

 

 


๊ฐœ์„ 

select
        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_.title as title9_8_ 
    from
        review review0_ 
    where
        exists (
            select
                1 
            from
                review_tag reviewtags3_ 
            where
                review0_.review_id=reviewtags3_.review_id 
                and reviewtags3_.property=?
        ) 
    order by
        review0_.created_at desc limit ?

10 rows retrieved starting from 1 in 1 s 683 ms (execution: 1 s 667 ms, fetching: 16 ms)

 

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE review0_ null ALL PRIMARY null null null 448427 100 Using filesort
1 SIMPLE <subquery2> null eq_ref <auto_distinct_key> <auto_distinct_key> 8 reviewmate.review0_.review_id 1 100 null
2 MATERIALIZED reviewtags3_ null ALL FKea2voymuynf2rmdx7ph30cwoe null null null 2177808 10 Using where

 

1. review_tag์— (review_id, property) ์ธ๋ฑ์Šค ์ ์šฉ

์šฐ์„ , ์„œ๋ธŒ ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ๊ฐ€์žฅ ๋งŽ์€ rows๋ฅผ ๋‹ค๋ฃจ๊ณ  ์žˆ๋Š” review_tag ๋ถ€๋ถ„๋ถ€ํ„ฐ ์ ์šฉํ•ด๋ณด์ž. ์กฐ๊ฑด์ ˆ์—์„œ review_id์™€ property๋ฅผ and ๋กœ ์ ์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ณตํ•ฉ ์ธ๋ฑ์Šค๋ฅผ ์ˆœ์„œ์— ๋งž๊ฒŒ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ธ๋ฑ์Šค๋ฅผ ํƒ€์ง€ ์•Š๋Š”๋‹ค.

create index review_tag_review_id_property_index on review_tag (review_id, property);

10 rows retrieved starting from 1 in 1 s 180 ms (execution: 1 s 166 ms, fetching: 14 ms)

 

id select_type table partitions type possible_keys key key_len ref rows fileted Extra
1 SIMPLE review0_ null ALL PRIMARY null null null 448427 100 Using filesort
1 SIMPLE <subquery2> null eq_ref <auto_distinct_key> <auto_distinct_key> 8 reviewmate.review0_.review_id 1 100 null
2 MATERIALIZED reviewtags3_ null index review_tag_review_id_property_index review_tag_review_id_property_index 775 null 2177808 10 Using where; Using index

 

์ƒ์„ฑํ•œ ์ธ๋ฑ์Šค๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ํƒ€์กŒ์œผ๋ฉฐ, ์ธ๋ฑ์Šค์— ํ•„์š”ํ•œ review_tag์˜ ์ปฌ๋Ÿผ๋“ค์ด ๋ชจ๋‘ ์žˆ์œผ๋ฏ€๋กœ ์ปคํผ๋ง ์ธ๋ฑ์Šค๊ฐ€ ์ž‘๋™ํ•œ ๋ชจ์Šต์ด๋‹ค. ์‹ค์ œ๋กœ 1667 ms -> 1166 ms๋กœ 30%๊ฐ€ ๋‹จ์ถ•๋๋‹ค.

Extra์— ์—ฌ๋Ÿฌ ์ „๋žต๋“ค์ด ์ƒ๊ฒผ๋Š”๋ฐ,

  • Using where : ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์ด ๋„˜๊ฒจ ์ค€ ๋ฐ์ดํ„ฐ (์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•ด ๊ฑธ๋Ÿฌ์ง„ ๋ฐ์ดํ„ฐ) ์ค‘์—์„œ MySQL ์•ค์ง„์ด ํ•œ๋ฒˆ ๋” ๊ฑธ๋ ค์•ผ ๋˜๋Š” ์กฐ๊ฑด (ํ•„ํ„ฐ๋ง ํ˜น์€ ์ฒดํฌ ์กฐ๊ฑด)์ด ์žˆ๋‹ค๋Š” ํ‘œ๊ธฐ๋‹ค. ํ•ด๋‹น ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋ฆฌ๋ทฐ ํƒœ๊ทธ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ exist()๋กœ ์ธํ•ด ๋ฐœ์ƒ๋˜๋Š”๋“ฏ ํ•˜์ง€๋งŒ ๋ถˆ๊ฐ€ํ”ผํ•˜๋‹ค.

MySQL ๋‚ด๋ถ€ ๊ตฌ์กฐ -   https://jojoldu.tistory.com/474

 

  • Using Index : ์ปค๋ฒ„๋ง ์ธ๋ฑ์Šค๊ฐ€ ์ ์šฉ๋˜์—ˆ๋‹ค๋Š” ํ‘œ๊ธฐ๋กœ์จ, ์‚ฌ์šฉ๋˜๋Š” ์ปฌ๋Ÿผ์ด ์ˆœ์„œ์— ๋งž๊ฒŒ ๋ชจ๋‘ ์ธ๋ฑ์Šค์— ํฌํ•จ๋˜์–ด ๋ฐ์ดํ„ฐ์— ์ง์ ‘ ์ ‘๊ทผํ•  ํ•„์š”๊ฐ€ ์—†์–ด ์ฟผ๋ฆฌ ํšจ์œจ์ด ์ข‹๋‹ค.
  • Using filesort : ์ธ๋ฑ์Šค๋กœ ์ •๋ ฌ๋˜์–ด ์žˆ์ง€ ์•Š์€ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ •๋ ฌ๋˜์—ˆ๋‹ค๋Š” ํ‘œ๊ธฐ๋‹ค. ORDER BY created_at๋กœ ์ธํ•œ ์ •๋ ฌ์„ ๋œปํ•œ๋‹ค.

 

2. review์— (created_at) ์ธ๋ฑ์Šค ์ ์šฉ

review ํ…Œ์ด๋ธ”์— Using filesort๊ฐ€ ํ‘œ๊ธฐ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ, ์ •๋ ฌ์— ์‚ฌ์šฉ๋˜๋Š” created_at ๋˜ํ•œ ์ธ๋ฑ์Šค๋ฅผ ์ ์šฉํ•ด๋ณด์ž.

create index review_created_at_index on reviewmate.review (created_at);

10 rows retrieved starting from 1 in 998 ms (execution: 985 ms, fetching: 13 ms)

 

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE review0_ null index PRIMARY review_created_at_index 9 null 10 100 Backward index scan
1 SIMPLE <subquery2> null eq_ref <auto_distinct_key> <auto_distinct_key> 8 reviewmate.review0_.review_id 1 100 null
2 MATERIALIZED reviewtags3_ null index review_tag_review_id_property_index review_tag_review_id_property_index 775 null 2177808 10 Using where; Using index

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ƒ์„ฑํ•œ ์ธ๋ฑ์Šค๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ํƒ€์กŒ์œผ๋ฉฐ, 1166 ms -> 998 ms๋กœ 15%๊ฐ€ ๋‹จ์ถ•๋๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ฒˆ์—๋Š” ์ƒˆ๋กœ์šด Extra๊ฐ€ ์ƒ๊ฒผ๋‹ค.

 

3. Descending index ์ ์šฉ

Backward index scan๋Š” ์ธ๋ฑ์Šค ๋ฆฌํ”„ ๋…ธ๋“œ๋ฅผ ์˜ค๋ฅธ์ชฝ ํŽ˜์ด์ง€๋ถ€ํ„ฐ ์™ผ์ชฝ์œผ๋กœ ์Šค์บ”ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๋œป์ด๋‹ค. ๋‹ค๋ฅธ ์ธ๋ฑ์Šค๋“ค์—๋Š” ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋Š” ์‹คํ–‰๊ณ„ํš์ธ๋ฐ, ์™œ ์—ฌ๊ธฐ์„œ๋งŒ ๋‚˜ํƒ€๋‚ ๊นŒ? ๊ต‰์žฅํžˆ ๊ฐ„๋‹จํ•œ๋ฐ, ๊ทธ ์ „์— ์ด์™€ ๊ด€๋ จ๋œ ์šฉ์–ด๋ฅผ ์ •๋ฆฌํ•ด๋ณด์ž

์šฉ์–ด ์„ค๋ช… -   https://tech.kakao.com/2018/06/19/mysql-ascending-index-vs-descending-index/

 

  • Ascending index : ์ž‘์€ ๊ฐ’์˜ ์ธ๋ฑ์Šค ํ‚ค๊ฐ€ B-Tree์˜ ์™ผ์ชฝ์œผ๋กœ ์ •๋ ฌ๋œ ์ธ๋ฑ์Šค
  • Descening index : zms ๊ฐ’์˜ ์ธ๋ฑ์Šค ํ‚ค๊ฐ€ B-Tree์˜ ์™ผ์ชฝ์œผ๋กœ ์ •๋ ฌ๋œ ์ธ๋ฑ์Šค
  • Forward index scan : (์ธ๋ฑ์Šค ํ‚ค์˜ ํฌ๊ณ  ์ž‘์Œ์— ๊ด€๊ณ„์—†์ด) ์ธ๋ฑ์Šค ๋ฆฌํ”„ ๋…ธ๋“œ์˜ ์™ผ์ชฝ ํŽ˜์ด์ง€๋ถ€ํ„ฐ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์Šค์บ”
  • Backward index scan : (์ธ๋ฑ์Šค ํ‚ค์˜ ํฌ๊ณ  ์ž‘์Œ์— ๊ด€๊ณ„์—†์ด) ์ธ๋ฑ์Šค ๋ฆฌํ”„ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ํŽ˜์ด์ง€๋ถ€ํ„ฐ ์™ผ์ชฝ์œผ๋กœ ์Šค์บ”

MySQL 8.0 ์ด์ „์—๋Š” ๋ฌธ๋ฒ•๋งŒ ์กด์žฌํ•˜๊ณ  ์ง€์›ํ•˜์ง€ ์•Š๋˜ Descending index์ธ๋ฐ, ์•ˆ๊ทธ๋ž˜๋„ ์ธ๋ฑ์Šค๊ฐ€ ๋งŽ์„์ˆ˜๋ก ํŠธ๋ ˆ์ด๋“œ ์˜คํ”„๊ฐ€ ํฐ ์ธ๋ฑ์Šค์ธ๋ฐ Ascending index๋ฅผ ์„ค์ •ํ•ด ์Šค์บ” ๋ฐฉํ–ฅ๋งŒ ๋ฐ”๊พธ๋ฉด ๋˜์ง€ ์™œ ๋ณ„๋„์˜ ์ธ๋ฑ์Šค๊ฐ€ ์กด์žฌํ•˜๋ƒ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ InnoDB ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์—์„œ Forward & Backward index scan ํŽ˜์ด์ง€ ๊ฐ„์—๋Š” Double linked list๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์œผ๋ฏ€๋กœ, ์Šค์บ” ๋ฐฉํ–ฅ์— ๋”ฐ๋ฅธ ์„ฑ๋Šฅ ์ฐจ์ด๋Š” ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค. ํ•˜์ง€๋งŒ Backward๊ฐ€ Forward์— ๋น„ํ•ด์„œ ๋А๋ฆด ์ˆ˜ ๋ฐ–์— ์—†๋Š” 2๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ๋‹ค.

3-1. Forward index scan์—๊ฒŒ ์ ํ•ฉํ•œ ํŽ˜์ด์ง€ ์ž ๊ธˆ ๊ตฌ์กฐ

InnoDB์˜ B-Tree ๋ฆฌํ”„ ํŽ˜์ด์ง€๋Š” Double linked list๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‚ฌ์‹ค ์–ด๋А ๋ฐฉํ–ฅ์ด๋“ ์ง€ ์ด๋™ ์ž์ฒด๋Š” ์ฐจ์ด๊ฐ€ ์—†๋‹ค. ํ•˜์ง€๋งŒ InnoDB ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์—์„œ๋Š” ํŽ˜์ด์ง€ ์ž ๊ธˆ ๊ณผ์ •์—์„œ ๋ฐ๋“œ๋ฝ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด B-Tree์˜ ์™ผ์ชฝ์—์„œ ์˜ค๋ฅธ์ชฝ ๋ฐฉํ–ฅ(Forward)๋กœ๋งŒ ์ž ๊ธˆ์„ ํš๋“ํ•˜๋„๋ก ํ•˜๊ณ  ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ Forward index scan์—์„œ๋Š” ๋‹ค์Œ ํŽ˜์ด์ง€ ์ž ๊ธˆ ํš๋“์ด ๋งค์šฐ ๊ฐ„๋‹จํ•˜์ง€๋งŒ, Backward index scan์—์„œ ์ด์ „ ํŽ˜์ด์ง€ ์ž ๊ธˆ์„ ํš๋“ํ•˜๋Š” ๊ณผ์ •์€ ์ƒ๋‹นํžˆ ๋ณต์žกํ•œ ๊ณผ์ •์„ ๊ฑฐ์ณ์•ผ ํ•œ๋‹ค

3-2. ๋‹จ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ์—ฐ๊ฒฐ๋œ ํŽ˜์ด์ง€ ๋‚ด์˜ ์ธ๋ฑ์Šค ๋ ˆ์ฝ”๋“œ ๊ตฌ์กฐ

ํด๋Ÿฌ์Šคํ„ฐ๋ง ์ธ๋ฑ์Šค์˜ ๊ฒฝ์šฐ B-Tree์˜ ๋ฆฌํ”„ ๋…ธ๋“œ๊ฐ€ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ฉฐ ์—ฌ๋Ÿฌ ๋ ˆ์ฝ”๋“œ๊ฐ€ ํ•˜๋‚˜๋กœ ๊ตฌ์„ฑ๋œ ํŽ˜์ด์ง€(Block)๊ฐ€ ๋ฆฌํ”„ ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ InnoDB ์—”์ง„์ด ํŠน์ • ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•  ๋•Œ, ๊ฒ€์ƒ‰ ๋Œ€์ƒ ๋ ˆ์ฝ”๋“œ(์ธ๋ฑ์Šค ๋ ˆ์ฝ”๋“œ)๊ฐ€ ์ €์žฅ๋œ ํŽ˜์ด์ง€๊นŒ์ง€๋Š” B-Tree๋ฅผ ์ด์šฉํ•ด์„œ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ 16K ์‚ฌ์ด์ฆˆ์ธ ์ธ๋ฑ์Šค ํŽ˜์ด์ง€๋ผ๋ฉด 600์—ฌ๊ฐœ ์ด์ƒ์˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์ €์žฅ๋  ์ˆ˜ ์žˆ๋‹ค. InnoDB๊ฐ€ 600์—ฌ๊ฐœ ๋ ˆ์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜์”ฉ ๋‹ค ์ˆœ์ฐจ์ ์œผ๋กœ ๋น„๊ตํ•œ๋‹ค๋ฉด ๋ ˆ์ฝ”๋“œ ๊ฒ€์ƒ‰์ด ์ƒ๋‹นํžˆ ๋А๋ฆด ๊ฒƒ์ด๋‹ค.

ํด๋Ÿฌ์Šคํ„ฐ๋ง ์ธ๋ฑ์Šค ๊ตฌ์กฐ -&nbsp;https://velog.io/@kbpark9898/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%9D%B8%EB%8D%B1%EC%8A%A4-B-tree-1

 

๋”ฐ๋ผ์„œ ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€ ๋‚ด์—์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ์ •๋ ฌ๋œ ๋ ˆ์ฝ”๋“œ 4~8๊ฐœ ์ •๋„์”ฉ ๋ฌถ์–ด์„œ ๋Œ€ํ‘œ ํ‚ค(๊ฐ€์žฅ ํฐ ์ธ๋ฑ์Šค ์—”ํŠธ๋ฆฌ ํ‚ค ๊ฐ’)๋ฅผ ์„ ์ •ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ๋Œ€ํ‘œ ํ‚ค๋“ค๋งŒ ๋ชจ์•„์„œ ๋ณ„๋„์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š”๋ฐ, ์ด๋ฅผ ํŽ˜์ด์ง€ ๋””๋ ‰ํ† ๋ฆฌ(Page directory)๋ผ๊ณ  ํ•œ๋‹ค. InnoDB๋Š” ํŠน์ • ํ‚ค ๊ฐ’์„ ๊ฒ€์ƒ‰ํ•  ๋•Œ ์ด์ง„ํƒ์ƒ‰์œผ๋กœ ๋Œ€ํ‘œ ํ‚ค๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ , ๋Œ€ํ‘œ ํ‚ค๋ฅผ ์ฐพ์œผ๋ฉด ๊ทธ๋•Œ๋ถ€ํ„ฐ ์ธ๋ฑ์Šค ํ‚ค ๊ฐ’ ์ˆœ์„œ๋Œ€๋กœ ์—ฐ๊ฒฐ๋œ Linked list๋ฅผ ์ด์šฉํ•ด ๋Œ€์ƒ ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•œ๋‹ค.

InnoDB page directory ๊ตฌ์กฐ - &nbsp; https://tech.kakao.com/2018/06/19/mysql-ascending-index-vs-descending-index/

 

๋ฌธ์ œ๋Š” Double linked list๋กœ ์—ฐ๊ฒฐ๋œ B-Tree ๋ฆฌํ”„ ํŽ˜์ด์ง€ ๊ตฌ์กฐ์™€๋Š” ๋‹ฌ๋ฆฌ, ํŽ˜์ด์ง€ ๋‚ด๋ถ€์˜ ๋ ˆ์ฝ”๋“œ๋“ค์€ Single linked list ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ Ascending index์—์„œ Forward index scan๊ณผ๋Š” ๋‹ฌ๋ฆฌ Backward index scan์€ ์˜จ์ „ํžˆ ์†๋„์˜ ์ด๋“์„ ๋ณด์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

๋˜ํ•œ, ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ ์ƒ ๋Š˜ created_at ์ •๋ ฌ์€ ์ตœ์‹ ์ˆœ(desc)๋งŒ ์ ์šฉ๋œ๋‹ค.

๋”ฐ๋ผ์„œ created_at ์ธ๋ฑ์Šค๋Š” Backward index๋กœ ๊ตฌ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

create index review_created_at_index on reviewmate.review (created_at desc);

10 rows retrieved starting from 1 in 901 ms (execution: 885 ms, fetching: 16 ms)

idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra

1 SIMPLE review0_ 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.review0_.review_id 1 100 null
2 MATERIALIZED reviewtags3_ null index review_tag_review_id_property_index review_tag_review_id_property_index 775 null 2177808 10 Using where; Using index

๊ด€๋ จํ•ด์„œ ์กฐ์‚ฌํ•˜๋Š” ๊ณผ์ •์—์„œ ์ƒˆ๋กœ ๋ฐฐ์šฐ๋Š” ๋‚ด์šฉ์ด ๋งŽ์•„ ์„œ๋ก ์ด ๊ธธ์—ˆ์ง€๋งŒ, ๊ฐ„๋‹จํ•˜๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. 998 ms -> 901 ms๋กœ 10%๊ฐ€ ๋‹จ์ถ•๋˜์—ˆ๋‹ค.

 

 


๋งˆ๋ฌด๋ฆฌ

origin review_tag index review index Descending index ๊ฒฐ๊ณผ
์ฟผ๋ฆฌ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„ 1667 ms 1166 ms 998 ms 901 ms
์ด์ „ ๋Œ€๋น„ ๋‹จ์ถ•๋ฅ  - 30% 15% 10%
์ตœ์ข… ๋‹จ์ถ•๋ฅ        46% ๋‹จ์ถ•

Datagrip์„ ํ†ตํ•ด ์ธ๋ฑ์Šค์™€ ์ฟผ๋ฆฌ๋“ค์„ ์กฐ์ž‘ํ•˜๊ณ  MySQL ์‹คํ–‰ ๊ณ„ํš์œผ๋กœ ์ ์šฉ๋˜๋Š” ์ธ๋ฑ์Šค์™€ ์ตœ์ ํ™” ์˜ต์…˜์„ ํ™•์ธํ•˜๊ณ , ๋ณตํ•ฉ ์ธ๋ฑ์Šค, ์ปค๋ฒ„๋ง ์ธ๋ฑ์Šค, ํด๋Ÿฌ์Šคํ„ฐ๋ง ์ธ๋ฑ์Šค๋ฅผ ์ ์šฉํ•˜์—ฌ subquery์™€ where, order by๊ฐ€ ํฌํ•จ๋œ ์ฟผ๋ฆฌ์˜ ์†๋„๋ฅผ ๊ฐœ์„ ํ–ˆ๋‹ค. ์ธ๋ฑ์Šค๋ฅผ ์ฒ˜์Œ ๋ฐฐ์šฐ๊ณ  ์ ์šฉํ•ด๋ณด์•˜๋Š”๋ฐ, ๋‹จ์ˆœํžˆ SQL์„ ์ž˜ ์งœ๋Š” ๊ฒƒ์„ ๋„˜์–ด MySQL ๋‚ด๋ถ€ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ณ  ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ์ฟผ๋ฆฌ ์‹คํ–‰ ๋™์ž‘์„ ์ตœ์ ํ™”ํ•ด๋‚˜๊ฐ€๋ฉด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋” ๊นŠ์ด ์ดํ•ดํ•˜๊ณ  ๋ฐฐ์šธ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

 


์ฐธ๊ณ ์ž๋ฃŒ

https://jojoldu.tistory.com/474
https://jojoldu.tistory.com/476
https://jojoldu.tistory.com/158
https://tech.kakao.com/2018/06/19/mysql-ascending-index-vs-descending-index/
https://velog.io/@kbpark9898/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%9D%B8%EB%8D%B1%EC%8A%A4-B-tree-1