๐ ๊ฐ์
๋ฐ๋ธ์ฝ์ค 4๊ธฐ์์ ๋๋ฌผ ๋ณดํธ์์ ๋ด์ฌ์ ๋งค์นญ ํ๋ซํผ์ธ AniFriends ๋ฅผ ๊ฐ๋ฐํ๋ฉด์ ๊ฒฝํํ ํ์ด์ง๋ค์ด์ ์ฑ๋ฅ ๊ฐ์ ๊ธฐ์ด๋ค. ๋ด์ฌ์๋ ๋ด์ฌ ๋ชจ์ง ๋ชฉ๋ก์ ์กฐํํ ์ ์์ผ๋ฉฐ ์๋ฒ์์๋ ๋ชจ์ง ๋ชฉ๋ก์ ํ์ด์ง๋ค์ด์ ์ผ๋ก ์๋ตํ๋ค. 100๋ง๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ์ฌ ์กฐํ ์ฑ๋ฅ์ ์ธก์ ํ์๋ค.
๐จ ๊ฐ์ ์
offset ์ด ๊ฐ๊ฐ 0/500,000/900,000์ผ ๋ ๋ค์๊ณผ ๊ฐ์ด ์ฝ 5~7์ด๊ฐ ์์๋๋ค.
offset: 0 / size: 20 |
![]() |
offset: 500,000 / size: 20 |
![]() |
offset: 900,000 / size: 20 |
![]() |
โ ์ธ๋ฑ์ค
์ฐ์ , ์ ๋ ฌ ๊ธฐ์ค์ธ created_at ์ ๋ด๋ฆผ์ฐจ์ ์ธ๋ฑ์ค๋ฅผ ์ ์ฉํด๋ณด์
์ธ๋ฑ์ค ์ ์ฉ ํ์ ์์์๊ฐ์ ๋ค์๊ณผ ๊ฐ๋ค.
offset: 0 / size: 20 |
![]() |
offset: 500,000 / size: 20 |
![]() |
offset: 900,000 / size: 20 |
![]() |
offset ์ด 0์ผ ๊ฒฝ์ฐ ์์์๊ฐ์ด 5.3์ด์์ 0.1์ด๋ก ์ฝ 50๋ฐฐ ๊ฐ์๋์๋ค. ํ์ง๋ง offset ์ด 500,000/900,000์ผ ๊ฒฝ์ฐ๋ ์ ํ ๊ฐ์ ๋์ง ์์๋ค. ์ด์ ๊ฐ ๋ฌด์์ผ๊น? ์คํ๊ณํ์ ํ์ธํด๋ณด์
offset: 0 / size: 20 |
![]() |
offset: 500,000 / size: 20 |
![]() |
offset: 900,000 / size: 20 |
![]() |
- type ์ ๋ณด๋ฉด offset ์ด 0์ผ ๋๋ index ์ด๊ณ 500,000/900,000์ผ ๋๋ ALL์ด๋ค.
- rows ๋ฅผ ๋ณด๋ฉด offset ์ด 0์ผ ๋๋ 20์ด๊ณ 500,000/900,000์ผ ๋๋ ์ฝ 1,000,000์ด๋ค.
- Extra ๋ฅผ ๋ณด๋ฉด 500,000/900,000์ผ ๋ Using filesort(์ถ๊ฐ์ ์ธ ์ ๋ ฌ ์์ ์ ์๋ฏธ) ๊ฐ ์กด์ฌํ๋ค.
์ด๋ฅผ ํตํด offset ์ด ์ด๋์ ๋ ์ปค์ง๋ฉด index ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ table full scan ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ๋ค๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. Mysql ๊ณต์๋ฌธ์์ ๋ฐ๋ฅด๋ฉด, ์ฟผ๋ฆฌ์์ ๋๋ถ๋ถ์ ํ์ ์ก์ธ์คํด์ผ ํ๋ ๊ฒฝ์ฐ ์ธ๋ฑ์ค๋ฅผ ํตํด ์์ ํ๋ ๊ฒ๋ณด๋ค ์์ฐจ์ ์ผ๋ก ์ฝ๋ ๊ฒ์ด ๋ ๋น ๋ฅด๋ค๊ณ ํ๋จํ๋ค๊ณ ํ๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ปค๋ฒ๋ง ์ธ๋ฑ์ค์ ์ปค์ ๋ฐฉ์์ ์ ์ฉํด๋ณด๋๋ก ํ์
โ ์ปค๋ฒ๋ง ์ธ๋ฑ์ค
์ปค๋ฒ๋ง ์ธ๋ฑ์ค๋ ์ฟผ๋ฆฌ์ ๋ชจ๋ ํญ๋ชฉ์ด ์ธ๋ฑ์ค ์ปฌ๋ผ์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋ ๊ฒ์ ์๋ฏธํ๋ค. ์ปค๋ฒ๋ง ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ์ค์ ๋ฐ์ดํฐ ๋ธ๋ก์ ์ ๊ทผํ ํ์ ์์ด ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ฌ ์ ์๋ค. ์ปค๋ฒ๋ง ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ ์ฟผ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ๋ค.
select * from recruitment r
join (select recruitment_id from recruitment
order by created_at desc
limit [offset], [size]) temp on r.recruitment_id = temp.recruitment_id
join shelter s r.shelter_id = s.shelter_id;
์ฒซ ๋ฒ์งธ join ์ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์ดํด๋ณด๋ฉด select ์ปฌ๋ผ์ pk ์ธ recruitment_id ์ด๊ณ order by ์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ์ ์ฉํ created_at ์ด๋ค. ์ฆ, ์ฟผ๋ฆฌ์ ๋ชจ๋ ํญ๋ชฉ์ด ์ธ๋ฑ์ค ์ปฌ๋ผ์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค. ์ด์ ์์ ์๊ฐ์ ํ์ธํด๋ณด์.
offset: 0 / size: 20 |
![]() |
offset: 500,000 / size: 20 |
![]() |
offset: 900,000 / size: 20 |
![]() |
์ปค๋ฒ๋ง ์ธ๋ฑ์ค๋ฅผ ์ ์ฉํ ๊ฒฐ๊ณผ offset ์ด 500,000/900,000 ์ธ ๊ฒฝ์ฐ๋ ์ฝ 40๋ฐฐ๊ฐ ๊ฐ์๋ 0.2~0.3์ด๊ฐ ์์๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ๊ทธ๋ ๋ค๋ฉด ์ปค๋ฒ๋ง ์ธ๋ฑ์ค๋ฅผ ์ ์ฉํ ํ์ ์คํ๊ณํ์ ์ด๋ป๊ฒ ๋ ๊น? offset ์ด 900,000 ์ผ ๊ฒฝ์ฐ๋ฅผ ํ์ธํด๋ณด์.
select_type ์ด DERIVED(from ์ ์ ์๋ธ์ฟผ๋ฆฌ) ์ธ ํ์ Extra ๋ฅผ ๋ณด๋ฉด Using index ์ด๋ค. ์ด๋ฅผ ํตํด ํด๋น ๋ถ๋ถ์ ์ปค๋ฒ๋ง ์ธ๋ฑ์ค๊ฐ ์ ์ฉ๋ ๊ฒ์ ์ ์ ์๋ค.
โ ์ปค์ ๋ฐฉ์
์ปค์๋ฐฉ์์ด๋ offset ์ 0 ์ผ๋ก ์ค์ ํ๊ณ ํน์ ์ง์ (์ปค์)์ where ๋ฌธ์ผ๋ก ์ค์ ํ์ฌ ๊ทธ ์ง์ ๋ถํฐ ํน์ ๊ฐ์๋งํผ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ์์ด๋ค. offset ์ด 0์ด๊ธฐ ๋๋ฌธ์ ํญ์ ์ฒซ ํ์ด์ง๋ฅผ ์กฐํํ๋ ๊ฒ๊ณผ ๋์ผํ ์ฑ๋ฅ์ ๋ผ ์ ์๋ค. ๋ด์ฌ ๋ชจ์ง๊ธ์ ์ ๋ ฌ ๊ธฐ์ค์ created_at ๊ธฐ์ค ๋ด๋ฆผ์ฐจ์์ด๊ณ created_at ๋ง์ ๊ฐ์ ๊ฒฝ์ฐ recruitment_id ๊ธฐ์ค ๋ด๋ฆผ์ฐจ์์ด๋ค. ์ปค์๋ฐฉ์์ ์ ์ฉํ ์ฟผ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ๋ค.
select * from recruitment r
join shelter s on s.shelter_id=r.shelter_id
where r.created_at < [created_at ์ปค์]
or (r.created_at = [created_at ์ปค์] and r.recruitment_id < [recruitment_id ์ปค์])
order by r.created_at desc
limit [size];
์ด์ offset ์ด 900,000 ์ธ ์ปค์๋ฅผ ์ ํํด์ ์์์๊ฐ์ ์ธก์ ํด๋ณด์. limit 899999, 1 ์ ํตํด 900,000 ๋ฒ์งธ์ ์ปค์๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค.
์คํ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ๋ค.
offset: 0 / size: 20 |
![]() |
์ปค๋ฒ๋ง ์ธ๋ฑ์ค๋ณด๋ค 50๋ฐฐ๊ฐ ๊ฐ์๋ 0.1 ์ด๊ฐ ์์๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ ๋ํ๋ ์ฆ์ ๋ด์ฌ ๋ชจ์ง ๋ชฉ๋ก ์กฐํ๊ฐ์ ๊ฒฝ์ฐ๋ ๋ฌดํ ์คํฌ๋กค ๋ฐฉ์์ด๋ฉฐ offset ์ ํ์๋ก ํ์ง์๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ด ์กฐ๊ธ ๋ ๋์ ์ปค์๋ฐฉ์์ ์ ํํ์๋ค.