DB

[CURSOR PAGING] μ»€μ„œ νŽ˜μ΄μ§•μ²˜λ¦¬.

girin_dev 2022. 8. 31. 20:51
728x90
λ°˜μ‘ν˜•

 

πŸ₯ž  μ˜€ν”„μ…‹ 기반 νŽ˜μ΄μ§•μ—μ„œ -> μ»€μ„œ 방식 νŽ˜μ΄μ§•μœΌλ‘œ λ³€κ²½ν•˜κΈ° 전에 미리 μ•Œμ•„λ³΄λ € ν•œλ‹€.

 

 

πŸ₯žπŸ₯ž μ˜€ν”„μ…‹ 기반 νŽ˜μ΄μ§•μ˜ 단점 : 

 

LIMIT / OFFSET 을 μ΄μš©ν•  경우 offset이 λŠ˜μ–΄λ‚˜λŠ” 양에 따라 λΉ„νš¨μœ¨μ μΈ λ™μž‘μ„ ν•˜κ²Œλœλ‹€. 

μ˜€ν”„μ…‹ μ΄μ „μ˜ 데이터λ₯Ό λͺ¨λ‘ μ‘°νšŒν•˜κ³  limit 와 offset에 ν•΄λ‹Ήν•˜λŠ” κ°’λ§Œ κ°€μ Έμ˜€λŠ” 방식이기 λ•Œλ¬Έμ— 
λŒ€λŸ‰μ˜ 데이터λ₯Ό κ°€μ Έμ˜€λŠ” νŽ˜μ΄μ§•μ— μ ν•©ν•˜μ§€ μ•Šλ‹€.
 
 
 
μ•„λž˜λŠ” μ—¬λŸ¬κ±΄μ˜ 데이터λ₯Ό μ‚­μ œν•˜κΈ° μœ„ν•œ μ“°λ ˆλ“œ μž‘μ—…μ— μ»€μ„œ νŽ˜μ΄μ§•μ„ μ μš©ν•˜λ €λ‹€κ°€ μ‹€νŒ¨ν•œ μΌ€μ΄μŠ€μ΄λ‹€. 
 
 

[AWS S3] object μ—¬λŸ¬ 건 μ‚­μ œ μš”μ²­ /220811 μˆ˜μ •

λͺ©μ  : μ‚­μ œ 총 νƒ€κ²Ÿ : DB상에 μžˆλŠ” 데이터 κΈ°μ€€μœΌλ‘œ 1μ–΅ 8천만 건에 ν•΄λ‹Ή. JAVA μ—μ„œ aws SDK λ₯Ό μ΄μš©ν•œ μ‚­μ œ μš”μ²­μ‹œμ—λŠ” 1회 μš”μ²­ μ΅œλŒ€ 였브젝트 μˆ˜κ°€ 1000개둜 μ œν•œλ˜μ–΄μžˆμŒ. λ”°λΌμ„œ λΉ„λ™κΈ°λ°©μ‹μœΌλ‘œ D

girinprogram93.tistory.com

πŸ§‡ μ»€μ„œ 값이 μΌμ •μΉ˜ μ•Šκ³  μΈλ±μŠ€λ‘œμ„œμ˜ κΈ°λŠ₯을 ν•   수 μ—†μ—ˆκΈ° λ•Œλ¬Έμ΄λ‹€. 

     λ‹Ήμ‹œμ— μΈλ±μŠ€κ°€ μ •ν™•ν•˜μ§€λ„ μ•Šκ³ , DB의 데이터λ₯Ό μ‹€μ œλ‘œ μ‚­μ œν•˜λŠ” λ“±,  인덱슀 μ»€μ„œκ°€ μ•„μ΄λ””λ‘œμ„œμ˜ κΈ°λŠ₯을 μ œλŒ€λ‘œ λͺ»ν•˜λŠ” λ°”λžŒμ—.. κ΅¬ν˜„ν•˜μ§€ λͺ»ν–ˆμŒ. 

 

 

 

πŸ₯  μ‹€νŒ¨ν•œ λ‚΄μš© μš”μ•½ 

s3 μŠ€ν† λ¦¬μ§€μ˜ thumbnail  νŒŒμΌμ„ μš©λŸ‰μœΌλ‘œ 인해 μ‚­μ œν•΄μ•Ό ν•  일이 μžˆμ—ˆλŠ”λ° aws s3 μŠ€ν† λ¦¬μ§€μ— μžˆλŠ” 였브젝트의 κ²½λ‘œλŠ” DB에 μ €μž₯λ˜μ–΄ μžˆμ—ˆκ³ , 

 

-->  aws s3 μ‚­μ œ μš”μ²­μ€ μ΅œλŒ€ 1000건만 지원  
--> μŠ€λ ˆλ“œλ₯Ό 4개 λŒλ €μ„œ 1000κ°œμ”© μ§€μš°μž! 
--> μ²˜λ¦¬ν•΄μ•Ό ν•  섬넀일 파일의 κ°œμˆ˜λŠ” 1μ–΅ 6천만? 8천만? κ±΄μ΄μ—ˆμŒ --> νŽ˜μ΄μ§•μ²˜λ¦¬μ™€ 같은 λ°©μ‹μ˜ 쿼리λ₯Ό λ‚ λ €μ„œ μ…€λ ‰ν•œ μ²œκ°œμ”© μŠ€λ ˆλ“œλ‘œ 돌리기 λ•Œλ¬Έμ—,
--> μ…€λ ‰νŠΈ 쿼리가 λ™μž‘ν•˜λŠ” 속도가 μ€‘μš”ν•¨ / 8천만?건이 λ„˜μ–΄κ°€λŠ” μ‹œμ λΆ€ν„°λŠ” μ…€λ ‰νŠΈ 쿼리의 속도가 1λΆ„ κ°€κΉŒμ΄ κ°€κΈ° μ‹œμž‘ν•¨. 
πŸ₯— 이 λΆ€λΆ„ 떄문에 μ»€μ„œ νŽ˜μ΄μ§• κ΅¬ν˜„ν•˜λ €κ³  ν–ˆμ—ˆμŒ. 
νŽ˜μ΄μ§•μ€ 점점 느렀질 수 μžˆλ‹€. ν…Œμ΄λΈ”μ˜ 크기가 μ»€μ§€λ©΄μ„œ 느렀질 μˆ˜λ„ 있고,
API 둜직이 λ³΅μž‘ν•΄μ§€λ©΄μ„œ 느렀질 μˆ˜λ„ μžˆλ‹€. 
ν•˜μ§€λ§Œ, μ• μ΄ˆμ— OFFSET, LIMIT으둜 μ‘°νšŒν•˜λŠ” 방식은 
μ•žμ—μ„œ μ½μ—ˆλ˜ 행을 λ‹€μ‹œ μ½μ–΄μ•Όν•˜κΈ° λ•Œλ¬Έμ— λ’€λ‘œ 갈수둝 λŠλ¦¬λ‹€. 

그리고 OFFSET, LIMIT은 인덱슀 μŠ€μΊ”κ³ΌλŠ” μ „ν˜€ μƒκ΄€μ—†λŠ” λͺ…λ Ήμ–΄κΈ°λ•Œλ¬Έμ— 인덱슀의 이점을 살릴 μˆ˜λ„ μ—†λ‹€. 
이 λ•Œ, κ°œμ„  κ°€λŠ₯ν•œ 방법이 No-Offset νŽ˜μ΄μ§• ν˜Ήμ€ μ»€μ„œ νŽ˜μ΄μ§•μ΄λΌκ³  λΆˆλ¦¬μš°λŠ” νŽ˜μ΄μ§• 기법이닀.
-->  ν•œλ‹¬ μ΄ν›„μ—λŠ” μƒˆλ‘œμš΄ μž₯λΉ„κ°€ λ“€μ–΄μ˜€κΈ° λ•Œλ¬Έμ— κ·Έ 전에 온라인 μŠ€ν† λ¦¬μ§€μ˜ μš©λŸ‰μ„ 확보해야함 ) 

 

 

 

πŸ₯   μ»€μ„œ 기반 νŽ˜μ΄μ§•.

 

μ˜€ν”„μ…‹κ³Ό 달리 μ–΄λ–€ λ°μ΄ν„°μ˜ λ‹€μŒμ— μžˆλŠ” 데이터λ₯Ό μš”μ²­ν•œλ‹€λŠ” 게 포인트. 

 

μ»€μ„œνŽ˜μ΄μ§•μœΌλ‘œ 바꾸기에 μ•žμ„œ 단점도 미리 보아야 ν•œλ‹€. 

 

좜처 : https://bbbicb.tistory.com/40

 

μ™œ μ˜€ν”„μ…‹ νŽ˜μ΄μ§•λ³΄λ‹€ μ»€μ„œ νŽ˜μ΄μ§•μΌκΉŒ?

Is offset pagination dead? Why cursor pagination is taking over Facebook’s developer page said it best: uxdesign.cc β€» 이 글은 μœ„ 글을 μ˜μ—­ν•œ κΈ€μž…λ‹ˆλ‹€. β€» μ œκ°€ μ΄ν•΄ν•œ 것을 ν† λŒ€λ‘œ μ•½κ°„ μˆ˜μ •ν–ˆμŠ΅λ‹ˆλ‹€...

bbbicb.tistory.com

 

싀행에 μ•žμ„œ μ‚¬μš©κ°€λŠ₯ν•œ κ²½μš°μΈμ§€ μ²΄ν¬ν•΄μ•Όν•œλ‹€. 

 

 

ν˜„μž¬ λ°”κΎΈλ €ν•˜λŠ” DB의 컬럼 쀑, task_idλŠ” sequence λ₯Ό μ‚¬μš©ν•˜λŠ” 방식이며, 
 

 

IDλ₯Ό μ‚­μ œν•˜λŠ” λ‘œμ§μ€ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€.  κ·ΈλŸ¬λ―€λ‘œ,

 

 

μΈλ±μŠ€λ‘œμ„œμ˜ 기쀀이 λͺ…ν™•ν•˜κ³ , νŽ˜μ΄μ§•μ—μ„œ λˆ„λ½λ  μœ„ν—˜μ΄ μ—†λ‹€. 

 

 

 

 

 ν˜„μž¬ μ“°λŠ” offset 방식 쿼리 : 

select
            a.task_id as task_id
            , a.src_path as src_path
            , a.tgt_path as tgt_path
            , a.task_status as task_status
            , a.progress as progress
            , a.task_start_dtm as task_start_dtm
            , a.task_end_dtm as task_end_dtm
            , a.assign_ip as agent_ip
            , a.creator_id as creator_id
            , to_char(a.created_dtm, 'YYYY-MM-DD HH24:MI:SS') as created_dtm 
      , b.type_nm as type_nm
      , c.task_rule_nm as task_rule_nm
from tb_task a
      ,tb_task_type b
      , tb_task_rule c
where a.type = b.type
and   
to_date(to_char(a.created_dtm, 'YYYY-MM-DD'),'YYYY-MM-DD') >= '2021-01-01'
and to_date(to_char(a.created_dtm, 'YYYY-MM-DD'), 'YYYY-MM-DD') <= '2025-01-01'      
and b.task_type_id = c.task_type_id
ORDER BY a.created_dtm desc
offset 500
LIMIT 100;

μ‹€ν–‰ κ³„νšμ€ λ‹€μŒκ³Ό κ°™λ‹€.  μ• μ΄ˆμ— 데이터 양이 μ μ–΄μ„œ 차이가 많이 μ•ˆλ‚˜λŠ” κ²½μš°μ΄λ‹€.

 

 

 

μ»€μ„œ νŽ˜μ΄μ§•μœΌλ‘œ λ°”κΏ€ 경우. 

select
            a.task_id as task_id
            , a.src_path as src_path
            , a.tgt_path as tgt_path
            , a.task_status as task_status
            , a.progress as progress
            , a.task_start_dtm as task_start_dtm
            , a.task_end_dtm as task_end_dtm
            , a.assign_ip as agent_ip
            , a.creator_id as creator_id
            , to_char(a.created_dtm, 'YYYY-MM-DD HH24:MI:SS') as created_dtm 
      , b.type_nm as type_nm
      , c.task_rule_nm as task_rule_nm
from tb_task a
      ,tb_task_type b
      , tb_task_rule c
where a.type = b.type
and task_id < 500
and   
to_date(to_char(a.created_dtm, 'YYYY-MM-DD'),'YYYY-MM-DD') >= '2021-01-01'
and to_date(to_char(a.created_dtm, 'YYYY-MM-DD'), 'YYYY-MM-DD') <= '2025-01-01'      
and b.task_type_id = c.task_type_id
ORDER by task_id desc, a.created_dtm desc
LIMIT 100;

 

 

 

 

좜처 κΈ€μ—μ„œλ„ λ§ν•˜μ§€λ§Œ 처음 1νŽ˜μ΄μ§€λŠ” μ„±λŠ₯이 μ’‹μ§€ μ•Šλ‹€.

 

offset..

 

μ΄ˆκΈ°κ°’ 1νŽ˜μ΄μ§€λ‘œ 보여쀀닀면.  pageλŠ” + 1 처리 ν•„μš”.
    WHERE task_id > (0 * 1(page)) limit 20;

ν˜„μž¬ 1 번째 νŽ˜μ΄μ§€μ—μ„œ λ‹€μŒ νŽ˜μ΄μ§€λ‘œ 갈 경우 :
    offset : task_id + (list * page)
    WHERE task_id > offset limit 20;

ν˜„μž¬ N 번째 νŽ˜μ΄μ§€μ—μ„œ λ‹€μŒ N번째 νŽ˜μ΄μ§€λ‘œ 갈경우 :
    offset : task_id + (list * NνŽ˜μ΄μ§€).
    WHERE task_id > offset  limit 20;

 

 

 

잘λͺ»λœ 점이 μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. 지적 λΆ€νƒλ“œλ¦½λ‹ˆλ‹€.

320x100
λ°˜μ‘ν˜•