<How to Think Like the Engine>
(* ์ง์ ์ฝ๊ณ ๋ฃ๊ณ ํด์ํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ค๋ฅ ๋ง์ ์ ์์ ์ฃผ์)
์์์์ ์ฌ์ฉํ ํ ์ด๋ธ์ StackOverflow2010.dbo.Users ํ ์ด๋ธ์ด๋ค.

PK๋ Id์ด๋ค. clustered index๊ฐ Id๋ก ์กํ์๋ค๋ ๊ฒ์ด๊ณ , ์ฌ์ค์ clustered index = ํ ์ด๋ธ ์์ฒด ๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค๊ณ ํ๋ค.

๋ธ๋ ํธ ์์ ์จ๊ป์ ์ฌ๋ ค์ฃผ์ pdf ์ ์ฒซ ์ฅ์ ๋ณด๋ฉด clustered index์ ๋ฐ์ดํฐ๊ฐ Id๋ก ์ ๋ ฌ๋์ด ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ์ ํ์ผ์ ๋ดค์ ๋ clustered index๋ Id๋ก ์ ๋ ฌ์ด ๋์ด ์๊ณ ๊ทธ ์ธ์ ์ปฌ๋ผ๋ค์ ๊ฐ๋ ๋ชจ๋ ๊ฐ์ง๊ณ ์๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค.
→ ์ ํํ๊ฒ ๋ฐ์ง์๋ฉด ์ด ํํ์ ๋ง์ง ์๋ ๊ฒ์ด๋ผ๊ณ ํ๋๋ฐ ์ผ๋จ ์ด๋ ๊ฒ ์ค๋ช ํด๋์ ๋ค๊ณ ํ๋ค. AboutMe ์ปฌ๋ผ์ด ์ข์ ์๋ค. ์ด ์ปฌ๋ผ์ ๋ณด๋ฉด ์ผ๋จ ๋ด์ฉ์ด ๊ธธ๋ค. 8KB (ํ์ด์ง ์ฌ์ด์ฆ) ๋ณด๋ค ๋ฐ์ดํฐ๊ฐ ๋ง์ ์๋ ์์ด ๋ณด์ธ๋ค. ์ด๋ฐ ๊ฒฝ์ฐ SQL Server๋ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋์ด ์๋ ํ์ด์ง์ ํฌ์ธํฐ๋ฅผ ์ ์ฅํ๊ฒ ๋๋ค. varchar(max), nvarchar(max), xml, json ๊ฐ์ ๋ฐ์ดํฐํ์ ์ ์ฌ์ฉํ ๋ ์๋ฐ ์ผ์ด ๋ฐ์ํ๋ค.
SQL Server๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์ต์ ๋จ์๋ก 8KB ์ง๋ฆฌ ํ์ด์ง๋ฅผ ์ฌ์ฉํ๋ค. ์ด ํ์ด์ง๋ผ๋ ๊ฒ์ ๋ฉ๋ชจ๋ฆฌ์ ์๋ ๋์คํฌ์ ์๋ ๋์ผํ๋ค.
์๋ฅผ ๋ค์ด, Users ํ ์ด๋ธ์์ ๋๊ตฐ๊ฐ์ LastAccessDate๋ฅผ ์ ๋ฐ์ดํธํ๊ณ ์ถ๋ค๊ณ ํ ๋, ๋๋ ๊ทธ ์ฌ๋์ LastAccessDate๋ฅผ ๊ฐ์ง๊ณ ์๋ ํ์ด์ง๋ฅผ ๊ฐ์ ธ์์ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ ค๋๊ณ , ์์ ์ ํ ๋ค์ ๋ค์ ๋์คํฌ์ ๊ฐ๋ค๋์ผ ํ๋ค. SQL Server๋ row ๋จ์๋ ํ ์ด๋ธ ๋จ์๋ก ์บ์ฑํ์ง ์๋๋ค. (ํ์ด์ง ๋จ์๋ก๋ง ํจ)
์ด์ ์์ผ๋ก ํด์ผํ ๊ฒ์ ๋ด๊ฐ SQL Server๊ฐ ๋์๋ค๊ณ ์๊ฐํ๊ณ ์ฌ์ฉ์๊ฐ ๋ณด๋ธ ์ฟผ๋ฆฌ์ ๋ํด ์ด๋ป๊ฒ ๋์ํ ์ง๋ฅผ ๋กค ํ๋ ์ํด๋ณด๋ ๊ฒ์ด๋ค. (๋ถ๋ด;)
โ ์ฒซ ๋ฒ์งธ ์ฟผ๋ฆฌ:
SELECT Id FROM dbo.Users;
์ผ๋จ ์ํฉ์ ๋ง๋ค์ด๋ณด์. ๋๋ ์ธ์ฌํ ์์์ด๊ณ ์ง์๋ค์ ์ธ์ฌ๊ธฐ๋ก์ ๊ด๋ฆฌํ๋ค. ์ด ์ธ์ฌ๊ธฐ๋ก ์ ๋ณด๋ ์ข
์ด๋ก ํ๋ฆฐํธ๋์ด ์ฐฝ๊ณ ์บ๋น๋ท์ ๋ฐํ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ์์ด ์ฌ๊ฐํ๊ฒ ๋ง๋ค. ๊ทธ๋ฆฌ๊ณ ์ธ์ฌํ ํ์ฅ๋๊ป์ ์ด ์ธ์ฌ๊ธฐ๋ก์ ๋ณด๊ณ ์ถ์ผ์ค ๋๋ง๋ค ๋ํํ
์ธ์ฌ๊ธฐ๋ก์ง๋ฅผ ๊ฐ๊ณ ์ค๋ผ๊ณ ์ํจ๋ค. ๋์ ์ผ์ ์ด ์ฌ๊ฐํ๊ฒ ๋ง์ ์ฌ์์ ์ธ์ฌ๊ธฐ๋ก์ง ์ค์์ ํ์ํ ๊ฒ๋ค์ ๋นจ๋ฆฌ ์ฐพ์์ ํ์ฅ๋๊ป ๊ฐ๋ค๋๋ฆฌ๋ ๊ฒ์ด๋ค.
์์ ์ฟผ๋ฆฌ๋๋ก๋ผ๋ฉด ํ์ฅ๋๊ป์๋ ์ ์ฌ์์ Id๋ฅผ ์๊ณ ์ถ์ผ์ ๊ฒ ๊ฐ๋ค. ๊ทธ๋ผ ๋๋ ์ด๋ป๊ฒ ํด์ผ ํ ๊น? ์ฐฝ๊ณ ์ ์๋ ์บ๋น๋ท์ผ๋ก ๊ฐ์ ํ ๋ช
ํ ๋ช
์ฉ ์กํ๋ ๋๋ก Id๋ฅผ ์ฐพ์์ ํ์ฅ๋ ๋ค๋ฆฌ๋๋ก ์ธ์น๋ค. (์ง์ง ์ฌ๋ฌด์ค์์๋ ๊ทธ๋ฌ์ง ๋ง๋๋ก ํ์.)

์๋ ๋์ถฉ ๋น์ทํ๊ฒ ํ๋ ๊ฒ ๊ฐ๋ค. ๊ทธ๋ผ ๋๋ ์ด์ ์บ๋น๋ท์์ ๋ด๊ฐ ๋์ผ๋ก ์ฝ์ด์ผ ํ๋ ์ข ์ด๊ฐ ๋์ฒด ๋ช ์ฅ์ธ์ง๋ ์๊ณ ์ถ๋ค. → SET STATISTICS IO ON

์ฌ๊ธฐ์ '๋ ผ๋ฆฌ์ ์ฝ๊ธฐ ์(Logical reads)'๋ SQL Server๊ฐ ์ฝ์ 8KB ํ์ด์ง ๊ฐ์์ด๋ค.
→ 7,405 * 8KB = 59MB
โ ๋ ๋ฒ์งธ ์ฟผ๋ฆฌ:
SELECT Id FROM dbo.Users
WHERE LastAccessDate > '2014/07/01';
ํ์ฅ๋์ ์ด๋ฒ์๋ LastAccessDate๊ฐ 2014๋ 7์ 1์ผ ์ดํ์ธ ์ฌ์๋ค์ Id๋ฅผ ๋ชจ์กฐ๋ฆฌ ๋ณด๊ณ ์ถ์ผ์๋ค. ์ด ๊ฒฝ์ฐ๋ ์ด๋ป๊ฒ ํด์ผํ ๊น? ์บ๋น๋ท์ ๊ฐ์ ์ธ์ฌ๊ธฐ๋ก์ง๋ฅผ ํ ์ฅ์ฉ(=ํ ํ์ด์ง์ฉ) ๊บผ๋ด์ ๋ชจ๋ ์ LastAccessDate๋ฅผ ํ์ธํ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ LastAccessDate๊ฐ ์กฐ๊ฑด์ ๋ง๋ ์ฌ์์ Id๋ฅผ ์ธ์น ๊ฒ์ด๋ค.

์, ๋ณ๋ ฌ์ฒ๋ฆฌ๋ฅผ ํ๋ค. ์์์๋ ๋ณ๋ ฌ ์ฒ๋ฆฌ ์๋ ์คํ๊ณํ์ ๋ณด์ฌ์ฃผ๊ณ ์์ผ๋๊น ์ผ๋จ ๋๊ฐ์ด ๋ง์ถฐ๋ณธ๋ค.

์ฒซ ๋ฒ์งธ ์ฟผ๋ฆฌ์ I/O๋ฅผ ๋น๊ตํด๋ณด์.

๊ฒฐ๊ณผ ๊ฑด์๋ ๊ฑฐ์ ๋ฐ์ผ๋ก ์ค์์ง๋ง logical reads ์๋ ๋์ผํ๋ค. ์๋๋ฉด ์ฒซ ๋ฒ์งธ ๊ฒฝ์ฐ์๋ ์ ์ฒด ์ธ์ฌ๊ธฐ๋ก์ง๋ฅผ ๋ค์ก์ ๊ฒ์ด๊ณ , ๋ ๋ฒ์งธ ๊ฒฝ์ฐ์๋ ๋ชจ๋ ์ฌ์์ LastAccessDate๊ฐ ์กฐ๊ฑด์ ๋ง๋์ง ์ฐพ๊ธฐ ์ํด ์ ์ฌ์์ ์ธ์ฌ๊ธฐ๋ก์ง๋ฅผ ๋ค์ก์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
Lesson : Using WHERE without matching index means scanning all the data.
์ ์ ํ ์ธ๋ฑ์ค ์์ด WHERE ์ ์ ์ฐ๋ ๊ฒ์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ค์บํ๊ฒ ๋ค๋ ์๋ฏธ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ๋ณ๋ ฌ์ฒ๋ฆฌ ๊ด๋ จํด์ ์ ์ ์ง๊ณ ๋์ด๊ฐ์๋ฉด, ๋ณ๋ ฌ ์ฒ๋ฆฌ ์ ์๊ธฐ๋ ์ถ๊ฐ read๊ฐ ์์ ์ ์๋ค.

์ฒซ ๋ฒ์งธ ์ฟผ๋ฆฌ์ ์คํ๊ณํ์ ๋ณด๋ฉด ๋จ์ผ ์ค๋ ๋๋ก ์คํ๋จ์ ์ ์ ์๋ค. ์ฐ๋ฆฌ ํ์ ์งฌ ์ ๋๋ ์ ๊ฐ ๋๋ฐ์ ์์ด์ ๋๋ง ์ฐพ์ผ๋ฌ ๊ฐ๋ค๋ ์ด์ผ๊ธฐ๋ค.
๋ ๋ฒ์งธ ์ฟผ๋ฆฌ์ ์คํ๊ณํ์ ๋ณด๋ฉด ๋ณ๋ ฌ์ฒ๋ฆฌ(Parallelism)๋ก ์คํ๋จ์ ์ ์ ์๋ค. ์ ์ ๊ณต์ฑ๋ก ์ธ์ฌํ ์ ์ ์ ๋ช ๋ช ๋ฝ์๊ณ ์ผ์ด ๋๋ฌด ๋ง์๋ณด์ด๋๊น ์ฌ๋์ ์ฌ๋ฌ ๋ช ํฌ์ ์์ผฐ๋ค.

์ด๋ ๊ฒ ๋ณ๋ ฌ๋ก ๋์์ ๊ฒฝ์ฐ (MAXDOP 1 OPTION์ ์ ๊ฑฐํ์ ๋) logical reads๊ฐ ๋ ๋์ด๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ์ฌ๊ธฐ์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋์ค์ ๋ค๋ฅธ ์์ ์๊ฐ ๋ ์ค๋ช ํด์ฃผ์ค ์์ ์ด๋ผ๊ณ ํ๋ค.
์คํ ๊ณํ์ ํ ๋ฒ ๋น๊ตํด ๋ณด์.

SELECT ๋ถ๋ถ์ ์ธ๋ถ ๋ด์ฉ์ ๋ณด๋ฉด Estimated Subtree Cost๋ผ๋ ๊ฒ์ด ์๋ค.

๋ ์ฟผ๋ฆฌ์ Estimated Subtree Cost๋ฅผ ๋น๊ตํด๋ณด๋, ๋ ๋ฒ์งธ ์ฟผ๋ฆฌ์ Estimated Subtree Cost๊ฐ ์ฒซ ๋ฒ์งธ ์ฟผ๋ฆฌ์ Estimated Subtree Cost๋ณด๋ค ์ด์ง ๋ฎ๋ค. ์ด๋ฌ๋ฉด ๋ณ๋ ฌ์ฒ๋ฆฌ๋ฅผ ํ ์ชฝ์ด ๋น์ฉ(cost)์ด ์ ๊ฒ ๋ ๊ฑธ๊น? ํ ๋ช ์ด ํ ์ผ์ ์ฌ๋ฌ ๋ช ์ด ๋๋ ์ ํ๋๊น?
→ No
์ด Estimated Subtree Cost๋ผ๋ ๊ฒ ๋ญ๋๋ฉด SQL Server๊ฐ ์ฟผ๋ฆฌ ๋๋ ค๋ณด๊ธฐ ์ ์ ๋์ถฉ CPU๋ I/O๊ฐ ์ผ๋งํผ ๋์ฌ ๊ฒ ๊ฐ๋ค๊ณ ์์ํ๋ ์์น ์ ๋๋ก ์๊ฐํ๋ฉด ๋๋ค๊ณ ํ๋ค. ์ฌ์ค SQL Server๋ ๋ด ์ปดํจํฐ์ ์ฝ์ด๋ ์คํ ๋ฆฌ์ง๊ฐ ์ผ๋ง๋ ๋น ๋ฅธ์ง๋ ๋ชจ๋ฅด๊ณ ๋ฉ๋ชจ๋ฆฌ ์ ๋๋ง ๋๊ฐ ์๊ณ ์๋๋ฐ ๊ทธ๊ฒ๋ ์ ํํ ์ ๊ณ ์๋ ๊ฑด ์๋๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๋ฐํ์ผ๋ก ์์ธกํ ๊ฒฐ๊ณผ๋ ๊ทธ๋ ๊ฒ ์ ํํ์ง๋ ์๋ค. ์ด ๊ฐ์ ๊ทธ๋ฅ how expensive SQL Server "thought" the query was going to be ์ ๊ฐ ์ ๋๋ก๋ง ์ฐธ๊ณ ํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค๊ณ ํ๋ค.
โ ์ธ ๋ฒ์งธ ์ฟผ๋ฆฌ:
SELECT Id FROM dbo.Users
WHERE LastAccessDate > '2014/07/01'
ORDER BY LastAccessDate;
์ด๋ฒ์๋ ์๊น ๊ทธ ๋ฐ์ดํฐ๋ฅผ LastAccessDate ์์ผ๋ก ํ์ฅ๋๊ป ์๋ ค๋๋ ค์ผ ํ๋ค. ์ด๋ฒ์๋ ์ด๋ป๊ฒ ํ ๊น?
๋จผ์ ์บ๋น๋ท์ผ๋ก ๊ฐ์ ํ ์ฅ์ฉ(=ํ ํ์ด์ง์ฉ) ๊บผ๋ด๋ณด๋ฉด์ ์กฐ๊ฑด์ ๋ง๋ (LastAccessDate > '2014/07/01') ์ฌ์์ ์ฐพ๊ณ , ์ถํ๋ฅผ ์ํด ํฌ์คํธ์์ ์ ์ด๋๋๋ค. ๋ญ ์ ์๊น? Id๋ LastAccessDate๋ฅผ ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง์ LastAccessDate๋ก ์ ๋ ฌํ ๋ค Id๋ฅผ ์ธ์น๋ฉด ๋ ๊ฒ ๊ฐ๋ค.

โ Clustered Index Scan
- ์ด ๋จ๊ณ์์๋ ์กฐ๊ฑด์ ๋ง๋ ๋ฐ์ดํฐ์ Id์ LastAccessDate๋ฅผ ๋ค์ ์ฐ์ฐ์์๊ฒ ์ธ์น๋ค. (์๋ ค์ค๋ค.)
โก Sort
- ์์ ์ฐ์ฐ์๊ฐ ์๋ ค์ค Id์ LastAccessDate๋ฅผ ๊ฐ์ง๊ณ ์ข ์ด์ ์ ์ด๊ฐ์ง๊ณ ์ ๋ ฌ์ ํ๋ค.
โข Parallelism (Gather Streams)
- ์ฌ๋ฌ ๋ช ์ด ํํฐ๋งํ๊ณ ์ ๋ ฌํด๋์ ๊ฒฐ๊ณผ๋ฅผ ํฉ์น๋ค.
์ ๋ ฌ์ด ์์ ๋์ ์์ ๋์ ์คํ๊ณํ์ ๋น๊ตํด๋ณด์.

์ ๋ ฌ์ ํ ์ชฝ์ Estimated Subtree Cost ๊ฐ์ด ๋ ํฌ๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ ๋ฐ์ Memory Grant๋ฅผ ์ดํด๋ณด๋ฉด ์ ๋ ฌ์ด ์๋ ์ชฝ์ ๊ฐ์ด ํจ์ฌ ๋ ํฐ ๊ฒ์ ์ ์ ์๋ค. ์ด๊ฒ์ ์๋ฏธ๋, We need space in order to write down our query results, ์ด๋ค.
SQL Server๊ฐ ์ฃผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ 3 ๊ฐ์ง ํฐ ์์ธ์ ์๋์ ๊ฐ๋ค.
- Caching data pages : tries to cache pages in memory as long as it can, because storage can be super slow
- Query workspace : all these little post-it notes, which are coincidentally the same 8KB page size as regular data pages
- Execution plans : when SQL Server has to build one of these big complex maps of how it's gonna process your query, it caches this for a while so that it doesn't have to rebuild that same execution plan again whenever that query plan comes back
Memory Grant์ ๋ํ ๋ถ๋ถ์ ์ข ๋ ์ดํด๋ณด์.

- DesiredMemory : how much SQL Server would love to have
- RequestedMemory : how much it actually asked for
- MaxUsedMamory : how much SQL Server actually consumed while it was running that query
To be continued...
'Database > Brent Ozar Unlimited' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| #5. ๋ ๋ฒ์งธ ์์ - 2 Lab: Indexing for WHERE (0) | 2021.07.09 |
|---|---|
| #4. ์ฒซ ๋ฒ์งธ ์์ - How to Think Like the Engine 2 (0) | 2021.07.08 |
| #2. ์ฒซ ๋ฒ์งธ ์์ - ์ฌ์ ์์ (0) | 2021.06.24 |
| #1. Brent Ozar ์์ (0) | 2021.06.14 |