WhatWhy [์ cursor ์ธ๊ฐ?]์ฐ์ํ ์ค์๊ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฅ๋ ฅ๋๋ฝ๋์ง ์๋ ๋ฐ์ดํฐ - ์ฌ์ฉ์์ ๊ธฐ๋ ๋ถ์์ฟผ๋ฆฌ ๊ฒฐ๊ณผ์ ๋ํ ์ค์ฝํHowOffsetCursorโ๏ธ Cursor ๋ฐฉ์ ํ์ด์ง ์ฌ์ฉ ์ ์ฃผ์์ REFER
What
- ํ์ด์ง์ด๋?
ํ์ด์ง์ ์ฑ
ํ์ด์ง์ฒ๋ผ ๋ฐ์ดํฐ๋ฅผ ๋ฌถ์์ผ๋ก ๋ถ๋ฆฌํ๋ ๊ณผ์
- ์ข ๋ฅ
- ์คํ์ ํ์ด์ง
OffSet
: ์ด๋ ๋ถํฐ ์์ํด์ ๊ฐ์ ธ์ฌ๊ฒ์ธ์ง?Limit
: ๋ช๊ฐ๋ฅผ ๊ฐ์ ธ์ฌ ๊ฒ์ธ์ง?
SELECT * FROM ${table_name} ORDER BY ${Column} OFFSET 10 LIMIT 5
ํ์ด์ง ๋ฒํผ๊ณผ ํจ๊ผ ์ฐ์ด๋ฉฐ ๋ฒํผ์ ํด๋ฆญํจ์ผ๋ก์จ ํ์ด์ง๋ฅผ ํํ ๋๊ธธ ์ ์์ต๋๋ค.

- ์ปค์ ํ์ด์ง
- Cursor - ์ฌ์ ์ ์๋ฏธ
- ์ค์๊ฐ ๋ฐ์ดํฐ์ ๋๋์ ๋ฐ์ดํฐ(ํ์ด์ค๋ถ, ์ฌ๋ , ํธ์ํฐ ๋ฑ)์ ๋ค๋ฃจ๋ ์น์ฌ์ดํธ์์ ์ฐ์ด๋ ํ์ด์ง ๋ฐฉ๋ฒ์ผ๋ก์จ, ํ๋ก ํธ์์ ๋ฌดํ ์คํฌ๋กค(์ธ์คํ ๊ทธ๋จ, ํ์ด์ค๋ถ์ฒ๋ผ ํ๋จ์ผ๋ก ๊ณ์ ์คํฌ๋กค ๋๋ ํ์ด์ง ๋ฐฉ์)์ ์ง์
์ฌ์ ์ ์๋ฏธ : ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปค์๋ ์ผ๋ จ์ ๋ฐ์ดํฐ์ ์์ฐจ์ ์ผ๋ก ์ก์ธ์คํ ๋ ๊ฒ์ ๋ฐ "ํ์ฌ ์์น"๋ฅผ ํฌํจํ๋ ๋ฐ์ดํฐ ์์ DB ์๋ฏธ : ํน์ SQL ๋ฌธ์ฅ์ ์ฒ๋ฆฌํ ๊ฒฐ๊ณผ๋ฅผ ๋ด๊ณ ์๋ ์์ญ์ ๊ฐ๋ฆฌํค๋ ์ผ์ข ์ ํฌ์ธํฐ ์ ๋๋ค.

Why [์ cursor ์ธ๊ฐ?]
์ค์๊ฐ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์
์ผ๋ก ๋ค๋ฃฐ์ ์๋ค๋ ์ ์
๋๋ค.
์๋ํ๋ฉด ์ปค์๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ ์ผ๋ก ์ ์งํ ๊ฒ์ ํ์๋ก ํ์ง ์๊ธฐ ๋๋ฌธ
์
๋๋ค.
์ฆ, ์๋ก์ด ๋ฐ์ดํฐ๊ฐ ์ถ๊ฐ๋๊ฑฐ๋ ์ ๊ฑฐ๋ ์ ์๋ ์ํฉ์์ ์ฌ์ฉ์๋ค์๊ฒ, ๊ทธ ๋ฐ์ดํฐ๋ค์ ์ ์์ ์ผ๋ก ์กฐํ๋ ์ ์์ ๊ฒ์
๋๋ค.์ฐ์ํ ์ค์๊ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฅ๋ ฅ
์คํ์
์ ๋จ์ํ ๋ ์ฝ๋๋ฅผ ์กฐํํ๊ธฐ ์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๊ฑด๋ ๋ฐ๋ ๋ ์ฝ๋์ ์๋ค.
์ฆ, ์์ฒญํ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ก ์กฐํํ๋ ๊ฒ์ด ์๋๋ผ, ์ด์ ์ ๋ฐ์ดํฐ๋ฅผ
๋ชจ๋ ์กฐํ
ํ๊ณ ๊ทธ ResultSet์์ ์คํ์
์ ์กฐ๊ฑด
์ผ๋ก ์๋ผ๋ด๋ ๊ฒ ์
๋๋ค.- ์คํ์ ์ฟผ๋ฆฌ ์์
SELECT * FROM ( SELECT ROWNUM() over (ORDER BY timestamp) rnum , A.* FROM table A ORDER BY timestamp ) WHERE ROWNUM BETWEEN 6 AND 10
- timestamp๋ฅผ ์ ๋ ฌ ๊ธฐ์ค์ผ๋ก ์ ์ฒด ๋ฐ์ดํฐ์ ํ๋ฒํธ๋ฅผ ์ถ๋ ฅํ๊ณ ์ด ๋ฒํธ๋ฅผ ๊ธฐ์ค์ผ๋ก ์๋ผ๋ด๋ ๊ฒ์ ๋๋ค.
- ์ด๊ฑด ์คํ์ ์ซ์๊ฐ ์ปค์ง์๋ก ํฐ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค. ๋ค๋์ ๋ฐ์ดํฐ๋ฅผ ํ ์คํธ ํ๋ ๋ถ๋ถ์์ ์์ฃผ ํฐ ์ฐจ์ด๋ฅผ ๋ณด์ ๋๋ค.

๋ ๊ณ ๋ คํด๋ด์ผ ํ ๊ฒ๋ค
๋ง์ง๋ง ํ์ด์ง๋ฅผ ์ด์ฉํ ํ๋ฅ ์ ์ผ๋ง์ ๋ ๋ ๊น?
0%๋ ์๋๊ฒ ์ง๋ง, ๋งค์ฐ ์์ ๊ฒ์ด๋ค.๊ทธ๋ ์ง๋ง ๊ตณ์ด 7๋ฐฑ๋ง๊ฐ์ ๋ฐ์ดํฐ๊ฐ ์๋๋๋ผ๋, ๊ทธ๋ํ์์ ํ์ธ ํ ์ ์๋ฏ์ด ์คํ์
ํ์ด์ง์ ์๊ฐ๋ณต์ก์ฑ O(N), O(offset+limit) ๋๋ฌธ์ ์คํ์
์ด ์ปค์ง์๋ก ์๊ฐ์ด ์ฆ๊ฐํด UX๋ ๊ฐ์ํฉ๋๋ค. ๋ฐ๋ฉด ์ปค์ ํ์ด์ง์ ๊ฒฝ์ฐ๋ O(1), O(limit)๋ก ํญ์ ์ผ์ ํฉ๋๋ค.
๋ฐ๋ผ์ ์ ๋ณด๋ค ํ์ด์ง ๋ก๋ฉ์ด ๋๋ ค์ง ๊ฒ๊ฐ์ ๋๋์ด ๋ ์ ์ด ์๋ค๋ฉด, ์๋ง๋ ๊ทธ๊ฑด ์คํ์
ํ์ด์ง์ ๋นํจ์จ์ฑ ๋๋ฌธ์
๋๋ค โผ๏ธ
๋๋ฝ๋์ง ์๋ ๋ฐ์ดํฐ - ์ฌ์ฉ์์ ๊ธฐ๋ ๋ถ์
- Offset ํ์ด์ง ์์ - sns์์ ์ต๊ทผ ํผ๋ 3๊ฐ์ ํผ๋๊ฐ ์ฌ๋ผ์๋ค.
์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ง๋ ํ์ด์ง๋น ๋ฐ์ดํฐ ๊ตฌ์ฑ ==== 1 ํ์ด์ง ======= A B F ==== 2 ํ์ด์ง ====== G H I ==== 3 ํ์ด์ง ====== . . . sns์์ ์ต๊ทผ ํผ๋ 3๊ฐ์ ํผ๋๊ฐ ์ฌ๋ผ์๋ค. ==== 1 ํ์ด์ง ======= A B C [new] ==== 2 ํ์ด์ง ====== D [new] E [new] F ==== 3 ํ์ด์ง ====== G H I
- ํด๋น ๋ฐ์ดํฐ์ ์๋ก์ด ์ฝ์
์ผ๋ก ํ์ฌ ๋ณด๊ณ ์๋ 2ํ์ด์ง์์ 3ํ์ด์ง๋ก ๊ฐ ๋ ๋๊ฐ์ ๋ฐ์ดํฐ๊ฐ ๋ณด์ด๊ฒ ๋ ์ ์๋ค. ์ฌ์ฉ์๋
?
ํ ์ ๋ ์์ต๋๋ค.
- ์ฝ์ ์ธ๋ก ์ญ์ ๊ฐ ์ด๋ฃจ์ด์ง ๊ฒฝ์ฐ๋ ๋น์ทํฉ๋๋ค.
- ์ค์ ์ ์ผ๋ก ์ฌ์ฉ๋ ์ฟผ๋ฆฌ ์์
SELECT * FROM table ORDER BY timestamp OFFSET 0 LIMIT 3 SELECT * FROM table ORDER BY timestamp OFFSET 3 LIMIT 3 SELECT * FROM table ORDER BY timestamp OFFSET 6 LIMIT 3 SELECT * FROM table ORDER BY timestamp OFFSET 9 LIMIT 3
- Cursor ํ์ด์ง ์์ - sns์์ ์ต๊ทผ ํผ๋ 3๊ฐ์ ํผ๋๊ฐ ์ฌ๋ผ์๋ค.
์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ง๋ ํ์ด์ง๋น ๋ฐ์ดํฐ ๊ตฌ์ฑ ==== 1 ํ์ด์ง ======= A B F ==== 2 ํ์ด์ง ====== G H I ==== 3 ํ์ด์ง ====== . . . sns์์ ์ต๊ทผ ํผ๋ 3๊ฐ์ ํผ๋๊ฐ ์ฌ๋ผ์๋ค. ==== 1 ํ์ด์ง ======= A B F ==== 2 ํ์ด์ง [๋ค์ ๋ฐ์ดํฐ ์์ฒญ ๊ฐ์ ธ์ด] ====== G H I ==== 3 ํ์ด์ง[๋ค์ ๋ฐ์ดํฐ ์์ฒญ ๊ฐ์ ธ์ด]====== . . .
- ์ ์ฝ์ ๋ ๋ฐ์ดํฐ๋ค์ ์๋ถ๋ฌ์ฌ๊น?
- ์คํ์ ์ ๋งค๋ฒ ํญ์ ๋ฐ์ดํฐ๋ค์ ๋ชจ๋ ๊ฐ์ ธ์์ ์ ๋ณ์ ํ์ง๋ง, ์ปค์๋ ์ง์ ๋ ๊ธฐ์ค ์ด์ธ์๋ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๊ฑฐ๋ฆฌ์ง ์๊ณ ํน์ ์กฐ๊ฑด ์ดํ์ ์๋ ๋ฐ์ดํฐ๋ค๋ง ์ ๋ณํด์ ๊ฐ์ ธ์ต๋๋ค.
SELECT * FROM table WHERE cursor > timestamp ORDER BY timestamp LIMIT 5
์ฟผ๋ฆฌ ๊ฒฐ๊ณผ์ ๋ํ ์ค์ฝํ
์ปค์ ํ์ด์ง๋ ๋จ์ ์ด ์กด์ฌํ๋ฏ๋ก ์ ๊ณ ๋ คํด์ผํ๋ค.[์ ๊ฒฝ์ธ๊ฒ ์์ฒญ ๋ง๋ค.]
์ ํ๋ ์ ๋ ฌ ๊ธฐ๋ฅ
- Firstname๊ณผ Lastname์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ ํ ์ด๋ธ ํ๋๋ฅผ ๊ฐ์ ํด๋ด ๋๋ค.
- ์ด ๊ฒฝ์ฐ๋ ์ปค์ ํ์ด์ง์ ๊ตฌํ์ ๋ฌธ์ ๋ฅผ ๋ฐ์์ํจ๋ค. ์๋ํ๋ฉด ์ปค์ ํ์ด์ง ์ ๋ ฌ์ ์๊ตฌ์ฌํญ ์ค ํ๋๋ ์ ๋ ฌํ ์ปฌ๋ผ์ ์ค๋ณต๋ ๊ฐ์ด ์กด์ฌํ๋ฉด ์๋๊ณ ,
์์ฐจ์ ์ด์ด์ผ ํ๋ค
๋ ๊ฒ ์ ๋๋ค. ์ปค์ ํ์ด์ง์ ์ฌ์ฉํ๋ ค๋ฉด"
์ด ๋ ์ฝ๋
๋ค์ ๋ ์ฝ๋๋ฅผ ์กฐํํด์ค"
๋ผ๊ณ ํ ์ ์๋ ํน์ ์ง์ ์ ์ปค์๋ก ์ง์ ํ ์ ์์ด์ผ ํฉ๋๋ค.
์ด๋ฐ ์๊ตฌ์ฌํญ ๋๋ฌธ์, ๋๋ถ๋ถ์ ์ปค์ ํ์ด์ง์ timestamp ์ปฌ๋ผ์ ๊ธฐ์ค์ผ๋ก ํ๋ค. ์๋ํ๋ฉด ์์ ๋จ์์ timestamp๋ ์์ฐจ์ ์ด๊ณ ๊ณ ์ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
Firstname
์ ์์ฐจ์ ์ผ ์๋ ์์ง๋ง ๊ณ ์ ํ์ง๋ ์์ต๋๋ค
. ์ฐ๋ฆฌ๋ ๊น, ๋ฐ, ์ต์จ๋ฅผ ์ ์ด๋ 100๋ช
์ ์๊ณ ์์ต๋๋ค. ๊ทธ๋์ ์ด๋ฐ ๊ฒฝ์ฐ ์ปค์๋ ๊ณ ์ ํ ๋ ์ฝ๋๊ฐ ์๋ ์ ์ฒด ๋ ์ฝ๋ ์งํฉ์ ๊ฐ๋ฆฌํฌ ์๋ ์์ต๋๋ค.
๋ฐ๋ผ์ ์ปค์๋ฅผ ๊ตฌํํ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ๋ฐ์ดํฐ๋ฅผ ๊ฑด๋ ๋ฐ๊ฑฐ๋ ์ค๋ณต
๋ ์ ์์ต๋๋ค.ํ์ ํ
์ด๋ธ์ ๊ฒฝ์ฐ ์ ๋ ฌ ๊ธฐ์ค์ผ๋ก ์ด๋ฉ์ผ์ด ๋ ์ข์ ์ ์์ต๋๋ค. ๊ณ ์ ํ๊ณ ์์ฐจ์ ์ด๋ผ๊ณ ๋ณผ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๊ทธ๋ฌ๋
์๊ตฌ์ฌํญ์ด
Lastname
๋๋
Firstname
์ผ๋ก ์ ๋ ฌํ๋ ๊ฒ์ด๋ผ๋ฉด ์ปค์ ํ์ด์ง์ด ์ ํฉํ์ง ์์ ์ ์์ต๋๋ค.
์ด๋ฆ๊ณผ ์ฑ์ ์ฐ๊ฒฐํ๊ฑฐ๋ ์ฌ๋ฌ ์ด์ ํํ์ ์ฌ์ฉํ์ฌ ๊ณ ์ ํ ์ด์ ๋ง๋ค ์ ์์ง๋ง ์ด๋ก ์ธํด ์ปค์ ํ์ด์ง์ด ์คํ์
ํ์ด์ง๋ณด๋ค ํจ์ฌ ๋๋ ค์ง ์๋ ์์ต๋๋ค. SQL๋ฌธ์์ ์ฐ๊ฒฐ ๋ฐ ํํ ๋น๊ต๋ ๋ชจ๋ ์๊ฐ๋ณต์ก๋ O(N), O(์ ์ฒด ๋ฐ์ดํฐ) ๋ฅผ ๊ฐ์ง๊ธฐ ๋๋ฌธ์
๋๋ค.- ์ปค์๋ฅผ ์๋ชป ์ฐ๋ ๊ฒฝ์ฐ ํฌํฌ๋ชฌ์ฐ์ ์ ํ

- ์ค์ ๋ก, ์ปค์ ํ์ด์ง์ด ์คํ์
ํ์ด์ง๋ณด๋ค ์ฒซ๋ฒ์งธ ํ์ด์ง๋ฅผ ํจ์ฌ ๋๋ฆฌ๊ฒ ์กฐํํ์ต๋๋ค. ์ง๊ด์ ์ผ๋ก ์ดํด๋์ง ์์ ์ ์์ง๋ง
Cursor(Concatenated)๊ฐ ์ฐํํฅ ํ๋ ์ด์ ๋ ๋ ์ฝ๋๊ฐ ๋ง์ ์ง์๋ก SELECT ํ๋ ๋ ์ฝ๋๊ฐ ์ ๊ธฐ ๋๋ฌธ
์ ๋๋ค.
How
Offset
- ์คํ๋ง jpa์ ์ ๊ณตํ๋ Pageable ๊ฐ์ฒด ์ฌ์ฉ

- Pageable ๊ตฌํ์ฒด์๋ PageRequest๋ผ๋ ๊ฐ์ฒด๊ฐ ์กด์ฌํฉ๋๋ค.
- ํด๋น PageRequest๋ ํด๋น ํ์ด์ง์ ํ์๋ก ํ๋ ๊ฒ๋ค์ด ์์ต๋๋ค.
- ๋ช๊ฐ์ฉ ๋ณด์ฌ์ค ๊ฒ์ธ์ง(
limit
) ์ด๋ ํ์ด์ง(offset
์ ์๋์ง๋ง ์ฐ๊ด์ด ์์.)๋ฅผ ๋ณผ๊ฒ์ธ์ง?์ ๋ํ ์ ๋ณด๊ฐ ํ์ํฉ๋๋ค. - ํด๋ผ์ด์ธํธ๋ก ๋ถํฐ ์ฌ์ด์ฆ์ ํ์ด์ง ์ ๋ณด๋ฅผ ๋ฐ์ต๋๋ค.
- PageRequest ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
public static PageRequest of(int page, int size, Sort sort) { // ํ์ด์ง๋ 0๋ถํฐ ์์ํ๋ค! ์ฌ์ฉ์๋ 1,2,3 ์ด์ง๋ง ์ปดํจํฐ ์ธ๊ณ๋ 0๋ฒ์งธ๋ถํฐ ์กด์ฌํจ์ ์ธ์งํด์ผ ํ๋ค. return new PageRequest(page, size, sort); }
Pageable ๊ฐ์ฒด๋ ๋ง์ ํธ์ ๊ธฐ๋ฅ๋ค์ ์ ๊ณตํฉ๋๋ค.
- ํ์ด์ง ๋ฒํธ
- ์ ํ์ด์ง ์กด์ฌ ์ฌ๋ถ ๋ฑ๋ฑโฆ

์ถ๊ฐ์ ์ผ๋ก ์ด๊ฒ๋ณด๋ค UI์์๋ ํ์ฌ ํ์ด์ง๋ค์ ๋ฒํธ๊ฐ ํ์ํ๋ ๋ฐ๋ก ์ปค์คํ ํด์ผํฉ๋๋ค!
Cursor
- ํ์ด์ง๋ฅผ ์ฒ์ ์ง์ ํ์ ๋๋ ๋ณ๋์ ํ์ด์ง์ ํ์ง ์๊ณ ์ผ์ ๊ฐ์๋งํผ ์กฐํํฉ๋๋ค.
- ์กฐํํ ๋ฐ์ดํฐ ์ค ๋ง์ง๋ง ๋ฐ์ดํฐ์ ์ปค์๊ฐ์ ์กฐํ ๋ฐ์ดํฐ์ ํจ๊ป ํ๋ก ํธ์ ๋๊ฒจ์ค๋๋ค.
- ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ๋์๋ ๋ฐฑ์๋์๊ฒ ์ปค์ ๊ฐ๊ณผ ํจ๊ป โ์ด ์ปค์ ๊ฐ ์ดํ์ ๋ฐ์ดํฐ๋ฅผ N๊ฐ ์กฐํ ํด์ฃผ์ธ์" ๋ผ๊ณ ์์ฒญ ๋ณด๋ ๋๋ค.
- ๋ฐฑ์๋๋ ์ปค์ ๊ฐ ์ดํ์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํฉ๋๋ค.(Member๋ฅผ id ์ญ์์ผ๋ก ์กฐํ, ์ต๊ทผ ์ปค์๊ฐ id = 10์ผ ๊ฒฝ์ฐ)
- ex) SELECT m From Member m WHERE id < 10 ORDER BY id DESC LIMIT 6;
โ๏ธ Cursor ๋ฐฉ์ ํ์ด์ง ์ฌ์ฉ ์ ์ฃผ์์
- ๋ฐ์ดํฐ ์ ์ค์ ์ฃผ์ ํ์ธ์ โผ๏ธ
์ค๋ณต์ด ๋ฐ์ํ๋ ์ปฌ๋ผ์ ์ปค์๋ก ์ฌ์ฉ ์ ๋ฐ์ดํฐ ์์ค์ด ๋ฐ์ํ ์ ์์ต๋๋ค.


์ฒ์ id๊ฐ 18, 17, 14์ธ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ ์๊ณ ์ปค์ ๊ฐ์ โ2022-08-14 09:53:39โ ๊ฐ ๋ฉ๋๋ค.
์ด์ ๋ค์ ํ์ด์ง๋ฅผ ๋ถ๋ฌ์ฌ ๊ฒฝ์ฐ์๋ โ2022-08-14 09:53:39โ ๋ณด๋ค ์ ์๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ฌ ๊ฒ๋๋ค.
ํ์ง๋ง id๊ฐ 13์ธ ๋ฐ์ดํฐ๋ ๋ง์ฐฌ๊ฐ์ง๋ก updatedAt์ด โ2022-08-14 09:53:39โ ์ด๋ฏ๋ก ์คํตํ๊ฒ ๋ฉ๋๋ค.
์๋ชป๋ ํ์ด์ง์ผ๋ก ๋ฐ์ดํฐ ์ ์ค์ด ๋ฐ์ํ ๊ฒ์
๋๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ์ค๋ณต๋๋๋ผ๋ ๋ค๋ฅธ ์ปฌ๋ผ๊ณผ ํจ๊ป ์ฌ์ฉํด ๋๋ฒ์งธ ๊ท์น์ ์ ํด์ผํฉ๋๋ค.
๋ค๋ฅธ ์ปฌ๋ผ๊ณผ ๊ฒฐํฉํด ์ฌ์ฉํ ๋์๋ ์ฟผ๋ฆฌ์ ๊ฐ๋ณํ ์ฃผ์ํด์ผํฉ๋๋ค. ์ปฌ๋ผ์ ๋ ๊ฐ ์ด์ ์ฌ์ฉํ๋คํด๋ ์ฟผ๋ฆฌ๊ฐ ์ ํํ์ง ์๋๋ค๋ฉด ์ฌ๋ฐ๋ฅธ ํ์ด์ง์ ํ ์ ์์ต๋๋ค.
์๋์ ๊ฐ์ด ์์ ์ผ์ด ์ต์ ์ธ ์์ผ๋ก ํ์ด์งํด ์ถ๋ ฅํ๋ ์ํฉ์ ๊ฐ์ ํฉ๋๋ค. updatedAt์ด ๊ฐ์ ๊ฒฝ์ฐ์ ์ค๋ณต๋์ง ์๋ ๊ฐ์ธ pk(id)๋ฅผ ์ญ์์ผ๋ก ์ ๋ ฌ ํด ์ฟผ๋ฆฌ์ ์กฐ๊ฑด์ ์ถ๊ฐ ํฉ๋๋ค.

- ์ฟผ๋ฆฌ๋ฅผ ์ ์ง์ผํฉ๋๋ค! โผ๏ธ
3๊ฐ์ฉ ํ์ด์ง ํ๋ค๊ณ ๊ฐ์ ํ์ ๋, ์ ๊ฐ ์ฒ์ ์์ฑํ๋ ์ฟผ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ผํ ๋ดค์ ๋์๋ ๋ฌธ์ ์์ด ํ์ด์ง ๋๋ ๋ฏ ํด ๋ณด์์ต๋๋ค.
SELECT * FROM post WHERE id < ${cursorId} and updatedAt <= ${cursorUpdatedAt} order by updatedAt desc, id desc limit 3;
# ์ฒ์ ๋ฐ์ดํฐ 3๊ฐ ๋ถ๋ฌ์ค๊ธฐ (๋ง์ง๋ง ๋ฐ์ดํฐ id = 14, updatedAt = 2022-08-14 09:53:39 SELECT * FROM post order by updatedAt desc, id desc limit 3;

# ๋ค์ ํ์ด์ง # cursor -> id = 14, updatedAt = 2022-08-14 09:53:39 # 13, 11, 10 SELECT * FROM post WHERE id < 14 and updatedAt <= '2022-08-14 09:53:39' order by updatedAt desc, id desc limit 3;

# ๋ค์ ํ์ด์ง # cursor -> id = 10, updatedAt = 2022-08-14 08:53:39 # 8, 7, 9 SELECT * FROM post WHERE id < 10 and updatedAt <= '2022-08-14 08:53:39' order by updatedAt desc, id desc limit 3;

ํ์ง๋ง ์ด ์ฟผ๋ฆฌ์๋ ๋ฌธ์ ์ ์ด ์์์ต๋๋ค. id๋ ํญ์ ๋ด๋ฆผ์ฐจ์์ด ์๋๋๋ค.
์ผ๋ถ์ ๊ฒ์๋ฌผ์ Update ํ๋ ์ํฉ์ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
์ฌ๋ฌ ๊ฒ์๋ฌผ๋ค์ ์์ ํด ๋ค์ ์์์ ๊ฐ์ด ๋ฐ์ดํฐ๊ฐ ๋ฐฐ์น๋ ๊ฒฝ์ฐ๋ฅผ ์๋ก ๋ค๊ฒ ์ต๋๋ค.

์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.

์ฒซ๋ฒ์งธ ํ์ด์ง ํ ์ปค์๋ updatedAt = 2022-09-04 12:00:00, id = 1์ ๊ฐ๋ฅดํต๋๋ค. ๋ค์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ฌ ๋๋ id๊ฐ 1๋ณด๋ค ์์ ๋ฐ์ดํฐ๊ฐ ์์ผ๋ฏ๋ก ๋ค๋ฅธ ๋ฐ์ดํฐ๋ค์ ์กฐํํ ์ ์์ต๋๋ค.
๊ธฐ์กด ์ฟผ๋ฆฌ๋ก๋ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ฌ ์๊ฐ ์์ต๋๋ค! ๋ฌธ์ ๊ฐ ์์ด ๋ณด์ด์ฃ ? ์ฟผ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํด์ผ ํฉ๋๋ค.
SELECT * FROM post WHERE updatedAt < ${cursorUpdatedAt} or (id < ${cursorId} and updatedAt == ${cursorUpdatedAt} ORDER BY updatedAt DESC, id DESC LIMIT 3;
์ฟผ๋ฆฌ๋ฅผ ๋ณ๊ฒฝํด์ ๋ค์ ์์ธํ ๋ณด๊ฒ ์ต๋๋ค.

- ์ฒ์ 3๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ต๋๋ค cursor ๋ id = 1, updatedAt = 2022-09-04 12:00:00 ์ ๋๋ค.
- ๊ทธ ๋ค์์ updatedAt < 2022-09-04 12:00:00 ์กฐ๊ฑด์ผ๋ก id๊ฐ 18, 17, 6 โฆ ์ธ ๊ฐ์ด ์กฐํ๋๊ณ
2022-09-04 12:00:00:00๊ณผ ์ค๋ณต๋๋ ๋ฐ์ดํฐ๊ฐ ์์ผ๋ฏ๋ก ๋ค์์ผ๋ก ๋์ด๊ฐ๋๋ค
์ด์ cursor๋ id = 6, updatedAt = 2022-09-04 08:00:00์
๋๋ค.
- ๋ค์์ผ๋ก updatedAt < 2022-09-04 08:00:00 ์กฐ๊ฑด์ผ๋ก 3-a ๋ถ๋ถ์ด ์กฐํ๋ฉ๋๋ค.
cursor updatedAt๋ณด๋ค ์์ ๋ฐ์ดํฐ๋ค์
๋๋ค.
id < 6 AND updatedAt = 2022-09-04 08:00:00 ์กฐ๊ฑด์ผ๋ก 3-b ๋ถ๋ถ์ด ์กฐํ๋ฉ๋๋ค.
cursor updatedAt๊ณผ ๊ฐ์ง๋ง id๊ฐ ๋ ์์ ๊ฒ ๋ค์
๋๋ค.
์ค๋ณต ๋ฌธ์ ๊ฐ ํด๊ฒฐ ๋์์ต๋๋ค.