์๊ฐ
ะ
์ฌ๊ธฐ์๋ ๋ค์๊ณผ ๊ด๋ จ๋ ์ฝ๋ ์ต์ ํ์ ๋ํ ๋ช ๊ฐ์ง ์ถ๊ฐ ์ ๊ทผ ๋ฐฉ์์ ์ ์ํฉ๋๋ค. LINQ ์ฟผ๋ฆฌ.
๊ทธ๊ฑฐ ์์์ด. ๋งํฌ(Language-Integrated Query)๋ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ฟผ๋ฆฌํ๊ธฐ ์ํ ๊ฐ๋จํ๊ณ ํธ๋ฆฌํ ์ธ์ด์
๋๋ค.
ะ LINQ์์ SQL๋ก DBMS์ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ธฐ์ ์ด๋ค. ์ด๋ ์ ์ธ์ ์ธ์ด๋ฅผ ํตํด ์ฟผ๋ฆฌ๊ฐ ๊ตฌ์ฑ๋ ํ ๋ค์์ผ๋ก ๋ณํ๋๋ ๋ฐ์ดํฐ ์์ ์ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. SQL ์ฟผ๋ฆฌ ํ๋ซํผ์ผ๋ก ์ ์ก๋์ด ์คํ์ ์ํด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ๋ก ์ ์ก๋ฉ๋๋ค. ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ DBMS๋ ๋ค์์ ์๋ฏธํฉ๋๋ค. MS SQL ์๋ฒ.
๊ทธ๋ฌ๋, LINQ ์ฟผ๋ฆฌ ์ต์ ์ผ๋ก ์์ฑ๋ ๊ฒ์ผ๋ก ๋ณํ๋์ง ์์ต๋๋ค SQL ์ฟผ๋ฆฌ, ์๋ จ๋ DBA๊ฐ ์ต์ ํ์ ๋ชจ๋ ๋์์ค๋ฅผ ๋ด์ ์์ฑํ ์ ์์ต๋๋ค. SQL ์ฟผ๋ฆฌ:
- ์ต์ ์ ์ฐ๊ฒฐ(JOIN) ๋ฐ ๊ฒฐ๊ณผ ํํฐ๋ง(WHERE)
- ์ฐ๊ฒฐ ๋ฐ ๊ทธ๋ฃน ์กฐ๊ฑด ์ฌ์ฉ ์ ๋ง์ ์ฐจ์ด
- ๊ต์ฒด ์กฐ๊ฑด์ ๋ค์ํ ๋ณํ IN ์ ์กด์ฌะธ ์, <> ์ผ์ง ์กด์ฌ
- ์์ ํ ์ด๋ธ, CTE, ํ ์ด๋ธ ๋ณ์๋ฅผ ํตํ ๊ฒฐ๊ณผ์ ์ค๊ฐ ์บ์ฑ
- ๋ฌธ์ฅ์ ์ฌ์ฉ (OPTION) ์ง์นจ ๋ฐ ํ ํํธ ํฌํจ ์ธ์ดํ๊ฐ๋๊ฐ (...)
- ์ ํ ์ค์ ์ค๋ณต๋ ๋ฐ์ดํฐ ์ฝ๊ธฐ๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํ ์๋จ ์ค ํ๋๋ก ์ธ๋ฑ์ฑ๋ ๋ทฐ ์ฌ์ฉ
๊ฒฐ๊ณผ์ ์ฃผ์ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์ SQL ์ฟผ๋ฆฌ ์ปดํ์ผํ ๋ LINQ ์ฟผ๋ฆฌ ์์น :
- ํ๋์ ์์ฒญ์ผ๋ก ์ ์ฒด ๋ฐ์ดํฐ ์ ํ ๋ฉ์ปค๋์ฆ ํตํฉ
- ๋์ผํ ์ฝ๋ ๋ธ๋ก์ ๋ณต์ ํ์ฌ ๊ถ๊ทน์ ์ผ๋ก ๋ถํ์ํ ๋ฐ์ดํฐ ์ฝ๊ธฐ๊ฐ ์ฌ๋ฌ ๋ฒ ๋ฐ์ํฉ๋๋ค.
- ๋ค์ค ๊ตฌ์ฑ ์์ ์กฐ๊ฑด ๊ทธ๋ฃน(๋ ผ๋ฆฌ์ "and" ๋ฐ "or") - ๋ฐ ะธ OR, ๋ณต์กํ ์กฐ๊ฑด์ผ๋ก ๊ฒฐํฉํ๋ฉด ํ์ํ ํ๋์ ์ ํฉํ ๋นํด๋ฌ์คํฐํ ์ธ๋ฑ์ค๋ฅผ ๊ฐ๋ ์ต์ ํ ํ๋ก๊ทธ๋จ์ด ๊ถ๊ทน์ ์ผ๋ก ํด๋ฌ์คํฐํ ์ธ๋ฑ์ค์ ๋ํด ์ค์บํ๊ธฐ ์์ํ๋ค๋ ์ฌ์ค๋ก ์ด์ด์ง๋๋ค(์ธ๋ฑ์ค ์ค์บ) ์กฐ๊ฑด ๊ทธ๋ฃน๋ณ
- ํ์ ์ฟผ๋ฆฌ์ ๊น์ ์ค์ฒฉ์ผ๋ก ์ธํด ๊ตฌ๋ฌธ ๋ถ์์ด ๋งค์ฐ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค. SQL ๋ฌธ ๊ฐ๋ฐ์ ์ธก์ ์ฟผ๋ฆฌ ๊ณํ ๋ถ์ ๋ฐ DBA
์ต์ ํ ๋ฐฉ๋ฒ
์ด์ ์ต์ ํ ๋ฐฉ๋ฒ์ผ๋ก ์ง์ ์ด๋ํด ๋ณด๊ฒ ์ต๋๋ค.
1) ์ถ๊ฐ ์ธ๋ฑ์ฑ
์ ์ฒด ์ฟผ๋ฆฌ๊ฐ ํ๋ ๋๋ ๋ ๊ฐ์ ๊ธฐ๋ณธ ํ ์ด๋ธ(์์ฉ ํ๋ก๊ทธ๋จ-์ฌ๋-์์ )์ ์ค์ฌ์ผ๋ก ํ์ค ์กฐ๊ฑด ์งํฉ(IsClosed, Canceled, Enabled, Status)์ ์ฌ์ฉํ์ฌ ๊ตฌ์ถ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ ์ ํ ํ ์ด๋ธ์ ํํฐ๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค. ์๋ณ๋ ์ํ์ ๋ํด ์ ์ ํ ์ธ๋ฑ์ค๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์ด ์๋ฃจ์ ์ ์ด๋ฌํ ํ๋๋ฅผ ์ ํํ๋ฉด ๋ฐํ๋๋ ์ฟผ๋ฆฌ ์งํฉ์ด ํฌ๊ฒ ์ ํ๋๋ ๊ฒฝ์ฐ์ ์ ํฉํฉ๋๋ค.
์๋ฅผ ๋ค์ด, 500000๊ฐ์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์์ต๋๋ค. ๊ทธ๋ฌ๋ ํ์ฑ ์ ํ๋ฆฌ์ผ์ด์ ์ 2000๊ฐ๋ฟ์ ๋๋ค. ๊ทธ๋ฌ๋ฉด ์ฌ๋ฐ๋ฅด๊ฒ ์ ํ๋ ์์ธ์ด ์ฐ๋ฆฌ๋ฅผ ๊ตฌํด์ค ๊ฒ์ ๋๋ค. ์ธ๋ฑ์ค ์ค์บ ํฐ ํ ์ด๋ธ์์ ๋นํด๋ฌ์คํฐํ ์ธ๋ฑ์ค๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ๋น ๋ฅด๊ฒ ์ ํํ ์ ์์ต๋๋ค.
๋ํ ์ฟผ๋ฆฌ ๊ณํ์ ๊ตฌ๋ฌธ ๋ถ์ํ๊ฑฐ๋ ์์คํ ๋ทฐ ํต๊ณ๋ฅผ ์์งํ๋ผ๋ ํ๋กฌํํธ๋ฅผ ํตํด ์ธ๋ฑ์ค ๋ถ์กฑ์ ์๋ณํ ์ ์์ต๋๋ค. MS SQL ์๋ฒ:
๋ชจ๋ ๋ทฐ ๋ฐ์ดํฐ์๋ ๊ณต๊ฐ ์ธ๋ฑ์ค๋ฅผ ์ ์ธํ๊ณ ๋๋ฝ๋ ์ธ๋ฑ์ค์ ๋ํ ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ธ๋ฑ์ค์ ์บ์ฑ์ ์๋ชป ์์ฑ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฉ์งํ๋ ๋ฐฉ๋ฒ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. LINQ ์ฟผ๋ฆฌ ะธ SQL ์ฟผ๋ฆฌ.
์ถ์ ๊ฐํนํ ๊ดํ์์ ์ ์ ์๋ฏ์ด ๊ธฐ์ ์ด ํน์ ๋ง๊ฐ์ผ๊น์ง ๋น์ฆ๋์ค ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ๊ฒ์ด ์ค์ํ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๋ฐ๋ผ์ ๊ณผ๋ํ ์์ฒญ์ ์บ์ฑ์ ํตํด ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์ ์ก๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
์ฌ์ฉ์์๊ฒ ํญ์ ์ต์ ๋ฐ์ดํฐ๊ฐ ํ์ํ ๊ฒ์ ์๋๋ฉฐ ์ฌ์ฉ์ ์ธํฐํ์ด์ค์ ์๋ต์ฑ์ด ํ์ฉ ๊ฐ๋ฅํ ์์ค์ด๊ธฐ ๋๋ฌธ์ ์ด๋ ๋ถ๋ถ์ ์ผ๋ก ์ ๋นํ๋ฉ๋๋ค.
์ด ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด ๋น์ฆ๋์ค ์๊ตฌ ์ฌํญ์ ํด๊ฒฐํ ์ ์์ง๋ง ๋ฌธ์ ํด๊ฒฐ์ ์ง์ฐ์์ผ ๊ถ๊ทน์ ์ผ๋ก ์ ๋ณด ์์คํ ์ ์ฑ๋ฅ์ ์ ํ์ํต๋๋ค.
๋ํ ์ถ๊ฐํ ํ์ ์ธ๋ฑ์ค๋ฅผ ๊ฒ์ํ๋ ๊ณผ์ ์์ ์ ์ ์ฌํญ์ด ์๋ค๋ ์ ์ ๊ธฐ์ตํ ๊ฐ์น๊ฐ ์์ต๋๋ค. MS์ SQL ๋ค์ ์กฐ๊ฑด์ ํฌํจํ์ฌ ์ต์ ํ๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ ์ ์์ต๋๋ค.
- ์ ์ฌํ ํ๋ ์งํฉ์ด ํฌํจ๋ ์ธ๋ฑ์ค๊ฐ ์ด๋ฏธ ์๋ ๊ฒฝ์ฐ
- ์ธ๋ฑ์ฑ ์ ํ์ผ๋ก ์ธํด ํ
์ด๋ธ์ ํ๋๋ฅผ ์ธ๋ฑ์ฑํ ์ ์๋ ๊ฒฝ์ฐ(์์ธํ ์ค๋ช
)
์ฌ๊ธฐ์ ).
2) ์์ฑ์ ํ๋์ ์๋ก์ด ์์ฑ์ผ๋ก ๋ณํฉ
๋๋ก๋ ์กฐ๊ฑด ๊ทธ๋ฃน์ ๊ธฐ์ด๋ก ์ฌ์ฉ๋๋ ํ ํ ์ด๋ธ์ ์ผ๋ถ ํ๋๊ฐ ํ๋์ ์ ํ๋๋ฅผ ๋์ ํ์ฌ ๋์ฒด๋ ์ ์์ต๋๋ค.
์ด๋ ์ผ๋ฐ์ ์ผ๋ก ์ ํ์ด ๋นํธ ๋๋ ์ ์์ธ ์ํ ํ๋์ ๊ฒฝ์ฐ ํนํ ๊ทธ๋ ์ต๋๋ค.
์ :
IsClosed = 0 AND ์ทจ์๋จ = 0 AND ํ์ฑํ๋จ = 0 ๋ก ๋์ฒด๋ฉ๋๋ค ์ํ = 1.
์ฌ๊ธฐ์ ์ด๋ฌํ ์ํ๊ฐ ํ ์ด๋ธ์ ์ฑ์์ง๋๋ก ์ ์ ์ํ ์์ฑ์ด ๋์ ๋ฉ๋๋ค. ๋ค์์ผ๋ก ์ด ์ ์์ฑ์ด ์์ธํ๋ฉ๋๋ค.
๋ถํ์ํ ๊ณ์ฐ ์์ด ๋ฐ์ดํฐ์ ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ ์ด๋ ์ฑ๋ฅ ๋ฌธ์ ์ ๋ํ ๊ทผ๋ณธ์ ์ธ ํด๊ฒฐ์ฑ ์ ๋๋ค.
3) ๋ทฐ์ ๊ตฌ์ฒดํ
๋ถํํ๊ฒ๋, LINQ ์ฟผ๋ฆฌ ์์ ํ ์ด๋ธ, CTE ๋ฐ ํ ์ด๋ธ ๋ณ์๋ ์ง์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ด ๊ฒฝ์ฐ๋ฅผ ์ต์ ํํ๋ ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ, ์ฆ ์ธ๋ฑ์ฑ๋ ๋ทฐ๊ฐ ์์ต๋๋ค.
์กฐ๊ฑด ๊ทธ๋ฃน(์ ์) IsClosed = 0 AND ์ทจ์๋จ = 0 AND ํ์ฑํ๋จ = 0 (๋๋ ๊ธฐํ ์ ์ฌํ ์กฐ๊ฑด ์งํฉ)์ ์ธ๋ฑ์ฑ๋ ๋ทฐ์์ ์ฌ์ฉํ์ฌ ํฐ ์งํฉ์์ ์์ ๋ฐ์ดํฐ ์กฐ๊ฐ์ ์บ์ฑํ๋ ์ข์ ์ต์ ์ด ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ ๋ทฐ๋ฅผ ๊ตฌ์ฒดํํ ๋ ๋ค์๊ณผ ๊ฐ์ ์ฌ๋ฌ ๊ฐ์ง ์ ํ ์ฌํญ์ด ์์ต๋๋ค.
- ํ์ ์ฟผ๋ฆฌ, ์ ์ฌ์ฉ ์กด์ฌ ๋ฅผ ์ฌ์ฉํ์ฌ ๊ต์ฒดํด์ผ ํฉ๋๋ค. JOIN
- ๋๋ ๋ฌธ์ฅ์ ์ฌ์ฉํ ์ ์๋ค UNION, UNION ALL, ์์ธ, ๊ต์ฐจ
- ํ ์ด๋ธ ํํธ์ ์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. OPTION
- ์ฌ์ดํด ์์ ๊ฐ๋ฅ์ฑ ์์
- ๋ค๋ฅธ ํ ์ด๋ธ์ ํ๋์ ๋ทฐ์ ๋ฐ์ดํฐ๋ฅผ ํ์ํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
์ธ๋ฑ์ฑ๋ ๋ทฐ ์ฌ์ฉ์ ์ค์ ์ด์ ์ ์ค์ ๋ก ์ธ๋ฑ์ฑํด์ผ๋ง ์ป์ ์ ์๋ค๋ ์ ์ ๊ธฐ์ตํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
๊ทธ๋ฌ๋ ๋ทฐ๋ฅผ ํธ์ถํ ๋ ์ด๋ฌํ ์ธ๋ฑ์ค๋ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ ๋ช ์์ ์ผ๋ก ์ฌ์ฉํ๋ ค๋ฉด ๋ค์์ ์ง์ ํด์ผ ํฉ๋๋ค. ํฌํจ(ํ์ฅ ์์).
๋ถํฐ LINQ ์ฟผ๋ฆฌ ํ ์ด๋ธ ํํธ๋ฅผ ์ ์ํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ๋ฏ๋ก ๋ค์ ํ์์ "๋ํผ"๋ผ๋ ๋ ๋ค๋ฅธ ํํ์ ๋ง๋ค์ด์ผ ํฉ๋๋ค.
CREATE VIEW ะะะฏ_ะฟัะตะดััะฐะฒะปะตะฝะธั AS SELECT * FROM MAT_VIEW WITH (NOEXPAND);
4) ํ ์ด๋ธ ํจ์ ์ฌ์ฉํ๊ธฐ
์ข ์ข LINQ ์ฟผ๋ฆฌ ๋ณต์กํ ๊ตฌ์กฐ์ ๋ทฐ๋ฅผ ์ฌ์ฉํ๋ ํฐ ํ์ ์ฟผ๋ฆฌ ๋ธ๋ก ๋๋ ๋ธ๋ก์ ๋งค์ฐ ๋ณต์กํ๊ณ ์ต์ ์ด ์๋ ์คํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ์ต์ข ์ฟผ๋ฆฌ๋ฅผ ํ์ฑํฉ๋๋ค.
ํ ์ด๋ธ ํจ์ ์ฌ์ฉ์ ์ฃผ์ ์ด์ LINQ ์ฟผ๋ฆฌ:
- ๋ทฐ์ ๊ฒฝ์ฐ์ ๊ฐ์ด ๊ฐ์ฒด๋ก ์ฌ์ฉ ๋ฐ ์ง์ ๋๋ ๊ธฐ๋ฅ์ด ์์ง๋ง ์
๋ ฅ ๋งค๊ฐ๋ณ์ ์ธํธ๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค.
ํจ์์์(@param1, @param2 ...)
๊ฒฐ๊ณผ์ ์ผ๋ก ์ ์ฐํ ๋ฐ์ดํฐ ์ํ๋ง์ด ๊ฐ๋ฅํฉ๋๋ค. - ํ
์ด๋ธ ํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์์์ ์ค๋ช
ํ ์ธ๋ฑ์ฑ๋ ๋ทฐ์ ๊ฒฝ์ฐ์ฒ๋ผ ๊ฐ๋ ฅํ ์ ํ์ด ์์ต๋๋ค.
- ํ
์ด๋ธ ํํธ:
๋ฅผ ํตํด ๋งํฌ ์ฟผ๋ฆฌํ ๋ ์ฌ์ฉํ ์ธ๋ฑ์ค๋ฅผ ์ง์ ํ๊ณ ๋ฐ์ดํฐ ๊ฒฉ๋ฆฌ ์์ค์ ๊ฒฐ์ ํ ์ ์์ต๋๋ค.
ํ์ง๋ง ํจ์์๋ ์ด๋ฌํ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.
์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ์ธ๋ฑ์ค ๋ฐ ๋ฐ์ดํฐ ๊ฒฉ๋ฆฌ ์์ค ์์ ์ ๋ํ ๊ท์น์ด ์ ์๋๋ ์๋นํ ์ผ์ ํ ์คํ ์ฟผ๋ฆฌ ๊ณํ์ ๋ฌ์ฑํ ์ ์์ต๋๋ค. - ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ์ธ๋ฑ์ฑ๋ ๋ทฐ์ ๋น๊ตํ์ฌ ๋ค์์ ์ป์ ์ ์์ต๋๋ค.
- ๋ณต์กํ ๋ฐ์ดํฐ ์ํ๋ง ๋ ผ๋ฆฌ(๋ฃจํ ์ฌ์ฉ ์์๋)
- ๋ค์ํ ํ ์ด๋ธ์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
- ์ ์ฌ์ฉ UNION ะธ ์กด์ฌ
- ํ
์ด๋ธ ํํธ:
- ์ ์ OPTION ๋์์ฑ ์ ์ด๋ฅผ ์ ๊ณตํด์ผ ํ ๋ ๋งค์ฐ ์ ์ฉํฉ๋๋ค. ์ต์
(MAXDOP N), ์ฟผ๋ฆฌ ์คํ ๊ณํ์ ์์์
๋๋ค. ์๋ฅผ ๋ค์ด:
- ์ฟผ๋ฆฌ ๊ณํ์ ๊ฐ์ ๋ก ๋ค์ ์์ฑํ๋๋ก ์ง์ ํ ์ ์์ต๋๋ค. ์ต์ (์ฌ์ปดํ์ผ)
- ์ฟผ๋ฆฌ ๊ณํ์ด ์ฟผ๋ฆฌ์ ์ง์ ๋ ์กฐ์ธ ์์๋ฅผ ์ฌ์ฉํ๋๋ก ๊ฐ์ ํ ์ง ์ฌ๋ถ๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค. ์ต์ (๊ฐ์ ๋ช ๋ น)
์ ๋ํ ์์ธํ ๋ด์ฉ OPTION ์ค๋ช
์ฌ๊ธฐ์ . - ๊ฐ์ฅ ์ข๊ณ ๊ฐ์ฅ ํ์ํ ๋ฐ์ดํฐ ์กฐ๊ฐ ์ฌ์ฉ:
์ธ๋ฑ์ฑ๋ ๋ทฐ์ ๊ฒฝ์ฐ์ฒ๋ผ ์บ์์ ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ธํธ๋ฅผ ์ ์ฅํ ํ์๊ฐ ์์ผ๋ฉฐ ์บ์์์ ์ฌ์ ํ ๋งค๊ฐ ๋ณ์๋ณ๋ก ๋ฐ์ดํฐ๋ฅผ ํํฐ๋งํด์ผ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด ํํฐ๊ฐ ์๋ ํ ์ด๋ธ์ด ์์ต๋๋ค. WHERE ์ธ ๊ฐ์ ํ๋๊ฐ ์ฌ์ฉ๋ฉ๋๋ค (a, b, c).์ผ๋ฐ์ ์ผ๋ก ๋ชจ๋ ์์ฒญ์๋ ์ผ์ ํ ์กฐ๊ฑด์ด ์์ต๋๋ค. a = 0 ๋ฐ b = 0.
๊ทธ๋ฌ๋ ํด๋น ๋ถ์ผ์ ๋ํ ์์ฒญ์ c ๋ ๋ณ์.
์กฐ๊ฑด์ ๋๋์ธ์ a = 0 ๋ฐ b = 0 ํ์ํ ๊ฒฐ๊ณผ ์งํฉ์ ์์ฒ ๊ฐ์ ๋ ์ฝ๋๋ก ์ ํํ๋ ๊ฒ์ ์ ๋ง ๋์์ด ๋์ง๋ง ั ์ ํ ๋ฒ์๋ฅผ 100๊ฐ์ ๋ ์ฝ๋๋ก ์ขํ๋๋ค.
์ฌ๊ธฐ์๋ ํ ์ด๋ธ ํจ์๊ฐ ๋ ๋์ ์ต์ ์ผ ์ ์์ต๋๋ค.
๋ํ ํ ์ด๋ธ ํจ์๋ ์คํ ์๊ฐ์ ์์ด ๋ ์์ธก ๊ฐ๋ฅํ๊ณ ์ผ๊ด์ฑ์ด ์์ต๋๋ค.
์
์ง๋ฌธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์๋ก ๋ค์ด ๊ตฌํ ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์์ฒญ์ด ์์ต๋๋ค SELECT, ์ฌ๋ฌ ํ ์ด๋ธ์ ๊ฒฐํฉํ๊ณ ํ๋์ ๋ทฐ(OperativeQuestions)๋ฅผ ์ฌ์ฉํ๋ฉฐ, ์ด๋ฉ์ผ์ ํตํด ์์์ ํ์ธํฉ๋๋ค. ์กด์ฌ) "์ด์ ์ง๋ฌธ":
์์ฒญ ๋ฒํธ 1
(@p__linq__0 nvarchar(4000))SELECT
1 AS [C1],
[Extent1].[Id] AS [Id],
[Join2].[Object_Id] AS [Object_Id],
[Join2].[ObjectType_Id] AS [ObjectType_Id],
[Join2].[Name] AS [Name],
[Join2].[ExternalId] AS [ExternalId]
FROM [dbo].[Questions] AS [Extent1]
INNER JOIN (SELECT [Extent2].[Object_Id] AS [Object_Id],
[Extent2].[Question_Id] AS [Question_Id], [Extent3].[ExternalId] AS [ExternalId],
[Extent3].[ObjectType_Id] AS [ObjectType_Id], [Extent4].[Name] AS [Name]
FROM [dbo].[ObjectQuestions] AS [Extent2]
INNER JOIN [dbo].[Objects] AS [Extent3] ON [Extent2].[Object_Id] = [Extent3].[Id]
LEFT OUTER JOIN [dbo].[ObjectTypes] AS [Extent4]
ON [Extent3].[ObjectType_Id] = [Extent4].[Id] ) AS [Join2]
ON [Extent1].[Id] = [Join2].[Question_Id]
WHERE ([Extent1].[AnswerId] IS NULL) AND (0 = [Extent1].[Exp]) AND ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[OperativeQuestions] AS [Extent5]
WHERE (([Extent5].[Email] = @p__linq__0) OR (([Extent5].[Email] IS NULL)
AND (@p__linq__0 IS NULL))) AND ([Extent5].[Id] = [Extent1].[Id])
));
๋ทฐ๋ ๋ค์ ๋ณต์กํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ํ์ ์ฟผ๋ฆฌ ์กฐ์ธ์ด ์๊ณ ์ ๋ ฌ์ ์ฌ์ฉํฉ๋๋ค. DISTINCT, ์ผ๋ฐ์ ์ผ๋ก ์๋นํ ๋ฆฌ์์ค ์ง์ฝ์ ์ธ ์์ ์ ๋๋ค.
OperativeQuestions์ ์ํ์ ์ฝ 10,000๊ฐ์ ๋ ์ฝ๋์ ๋๋ค.
์ด ์ฟผ๋ฆฌ์ ์ฃผ์ ๋ฌธ์ ์ ์ ์ธ๋ถ ์ฟผ๋ฆฌ์ ๋ ์ฝ๋์ ๋ํด ๋ด๋ถ ํ์ ์ฟผ๋ฆฌ๊ฐ [Email] = @p__linq__0์ ๋ํด [OperativeQuestions] ๋ณด๊ธฐ์์ ์คํ๋๋ค๋ ๊ฒ์ ๋๋ค. ์ด๋ฅผ ํตํด ์ถ๋ ฅ ์ ํ์ ์ ํํ ์ ์์ต๋๋ค. ์กด์ฌ) ์ต๋ ์๋ฐฑ ๊ฐ์ ๋ ์ฝ๋.
๊ทธ๋ฆฌ๊ณ ์๋ธ์ฟผ๋ฆฌ๋ [Email] = @p__linq__0์ผ๋ก ํ๋ฒ ๋ ์ฝ๋๋ฅผ ๊ณ์ฐํ๊ณ , ์ด ๋ช๋ฐฑ๊ฐ์ ๋ ์ฝ๋๋ฅผ ์ง๋ฌธ์ผ๋ก ID๋ก ์ฐ๊ฒฐํด์ผ ์ฟผ๋ฆฌ๊ฐ ๋นจ๋ผ์ง๋ ๊ฒ์ฒ๋ผ ๋ณด์ผ ์๋ ์์ต๋๋ค.
์ค์ ๋ก ๋ชจ๋ ํ ์ด๋ธ์๋ ์์ฐจ์ ์ธ ์ฐ๊ฒฐ์ด ์์ต๋๋ค. ์ฆ, OperativeQuestions์ Id์ Id ์ง๋ฌธ์ ์ผ์น ์ฌ๋ถ๋ฅผ ํ์ธํ๊ณ ์ด๋ฉ์ผ๋ก ํํฐ๋งํฉ๋๋ค.
์ค์ ๋ก ์์ฒญ์ ์๋ง ๊ฐ์ OperativeQuestions ๋ ์ฝ๋์ ๋ชจ๋ ์๋ํ์ง๋ง ์ด๋ฉ์ผ์ ํตํด ๊ด์ฌ ์๋ ๋ฐ์ดํฐ๋ง ํ์ํฉ๋๋ค.
OperativeQuestes ๋ณด๊ธฐ ํ ์คํธ:
์์ฒญ ๋ฒํธ 2
CREATE VIEW [dbo].[OperativeQuestions]
AS
SELECT DISTINCT Q.Id, USR.email AS Email
FROM [dbo].Questions AS Q INNER JOIN
[dbo].ProcessUserAccesses AS BPU ON BPU.ProcessId = CQ.Process_Id
OUTER APPLY
(SELECT 1 AS HasNoObjects
WHERE NOT EXISTS
(SELECT 1
FROM [dbo].ObjectUserAccesses AS BOU
WHERE BOU.ProcessUserAccessId = BPU.[Id] AND BOU.[To] IS NULL)
) AS BO INNER JOIN
[dbo].Users AS USR ON USR.Id = BPU.UserId
WHERE CQ.[Exp] = 0 AND CQ.AnswerId IS NULL AND BPU.[To] IS NULL
AND (BO.HasNoObjects = 1 OR
EXISTS (SELECT 1
FROM [dbo].ObjectUserAccesses AS BOU INNER JOIN
[dbo].ObjectQuestions AS QBO
ON QBO.[Object_Id] =BOU.ObjectId
WHERE BOU.ProcessUserAccessId = BPU.Id
AND BOU.[To] IS NULL AND QBO.Question_Id = CQ.Id));
DbContext์ ์ด๊ธฐ ๋ทฐ ๋งคํ(EF Core 2)
public class QuestionsDbContext : DbContext
{
//...
public DbQuery<OperativeQuestion> OperativeQuestions { get; set; }
//...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Query<OperativeQuestion>().ToView("OperativeQuestions");
}
}
์ด๊ธฐ LINQ ์ฟผ๋ฆฌ
var businessObjectsData = await context
.OperativeQuestions
.Where(x => x.Email == Email)
.Include(x => x.Question)
.Select(x => x.Question)
.SelectMany(x => x.ObjectQuestions,
(x, bo) => new
{
Id = x.Id,
ObjectId = bo.Object.Id,
ObjectTypeId = bo.Object.ObjectType.Id,
ObjectTypeName = bo.Object.ObjectType.Name,
ObjectExternalId = bo.Object.ExternalId
})
.ToListAsync();
์ด ํน๋ณํ ๊ฒฝ์ฐ, ์ฐ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฅผ ์ฑ์ฐ๊ณ ์ต์ ์ํ๋ก ์ ์งํ๊ธฐ ์ํ ๋ฉ์ปค๋์ฆ์ด ํ์ํ ๊ธฐ์ฑ ๊ฒฐ๊ณผ(โํ์ฑ ์ฟผ๋ฆฌโ)๊ฐ ํฌํจ๋ ๋ณ๋์ ํ ์ด๋ธ์ ๋์ ํ์ง ์๊ณ ์ธํ๋ผ ๋ณ๊ฒฝ ์์ด ์ด ๋ฌธ์ ์ ๋ํ ์๋ฃจ์ ์ ๊ณ ๋ คํ๊ณ ์์ต๋๋ค. .
์ด๊ฒ์ด ์ข์ ํด๊ฒฐ์ฑ ์ด๊ธฐ๋ ํ์ง๋ง ์ด ๋ฌธ์ ๋ฅผ ์ต์ ํํ ์ ์๋ ๋ ๋ค๋ฅธ ์ต์ ์ด ์์ต๋๋ค.
์ฃผ์ ๋ชฉ์ ์ OperativeQuestions ๋ณด๊ธฐ์์ [Email] = @p__linq__0์ผ๋ก ํญ๋ชฉ์ ์บ์ํ๋ ๊ฒ์ ๋๋ค.
ํ ์ด๋ธ ํจ์ [dbo].[OperativeQuestionsUserMail]๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋์ ํฉ๋๋ค.
์ด๋ฉ์ผ์ ์ ๋ ฅ ๋งค๊ฐ๋ณ์๋ก ๋ณด๋ด๋ฉด ๊ฐ ํ ์ด๋ธ์ด ๋ฐํ๋ฉ๋๋ค.
์์ฒญ ๋ฒํธ 3
CREATE FUNCTION [dbo].[OperativeQuestionsUserMail]
(
@Email nvarchar(4000)
)
RETURNS
@tbl TABLE
(
[Id] uniqueidentifier,
[Email] nvarchar(4000)
)
AS
BEGIN
INSERT INTO @tbl ([Id], [Email])
SELECT Id, @Email
FROM [OperativeQuestions] AS [x] WHERE [x].[Email] = @Email;
RETURN;
END
์ด๋ ์ฌ์ ์ ์๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ํ ์ด๋ธ์ ๋ฐํํฉ๋๋ค.
OperativeQuestionsUserMail์ ๋ํ ์ฟผ๋ฆฌ๊ฐ ์ต์ ์ด๊ณ ์ต์ ์ ์ฟผ๋ฆฌ ๊ณํ์ ๊ฐ์ง๋ ค๋ฉด ์๊ฒฉํ ๊ตฌ์กฐ๊ฐ ํ์ํฉ๋๋ค. ๋ฐํ ํ ์ด๋ธ์ ๋ฐํ์ผ๋ก ๋ฐํ...
์ด ๊ฒฝ์ฐ ํ์ ์ฟผ๋ฆฌ 1์ด ์ฟผ๋ฆฌ 4๋ก ๋ณํ๋ฉ๋๋ค.
์์ฒญ ๋ฒํธ 4
(@p__linq__0 nvarchar(4000))SELECT
1 AS [C1],
[Extent1].[Id] AS [Id],
[Join2].[Object_Id] AS [Object_Id],
[Join2].[ObjectType_Id] AS [ObjectType_Id],
[Join2].[Name] AS [Name],
[Join2].[ExternalId] AS [ExternalId]
FROM (
SELECT Id, Email FROM [dbo].[OperativeQuestionsUserMail] (@p__linq__0)
) AS [Extent0]
INNER JOIN [dbo].[Questions] AS [Extent1] ON([Extent0].Id=[Extent1].Id)
INNER JOIN (SELECT [Extent2].[Object_Id] AS [Object_Id], [Extent2].[Question_Id] AS [Question_Id], [Extent3].[ExternalId] AS [ExternalId], [Extent3].[ObjectType_Id] AS [ObjectType_Id], [Extent4].[Name] AS [Name]
FROM [dbo].[ObjectQuestions] AS [Extent2]
INNER JOIN [dbo].[Objects] AS [Extent3] ON [Extent2].[Object_Id] = [Extent3].[Id]
LEFT OUTER JOIN [dbo].[ObjectTypes] AS [Extent4]
ON [Extent3].[ObjectType_Id] = [Extent4].[Id] ) AS [Join2]
ON [Extent1].[Id] = [Join2].[Question_Id]
WHERE ([Extent1].[AnswerId] IS NULL) AND (0 = [Extent1].[Exp]);
DbContext(EF Core 2)์ ๋ทฐ ๋ฐ ํจ์ ๋งคํ
public class QuestionsDbContext : DbContext
{
//...
public DbQuery<OperativeQuestion> OperativeQuestions { get; set; }
//...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Query<OperativeQuestion>().ToView("OperativeQuestions");
}
}
public static class FromSqlQueries
{
public static IQueryable<OperativeQuestion> GetByUserEmail(this DbQuery<OperativeQuestion> source, string Email)
=> source.FromSql($"SELECT Id, Email FROM [dbo].[OperativeQuestionsUserMail] ({Email})");
}
์ต์ข LINQ ์ฟผ๋ฆฌ
var businessObjectsData = await context
.OperativeQuestions
.GetByUserEmail(Email)
.Include(x => x.Question)
.Select(x => x.Question)
.SelectMany(x => x.ObjectQuestions,
(x, bo) => new
{
Id = x.Id,
ObjectId = bo.Object.Id,
ObjectTypeId = bo.Object.ObjectType.Id,
ObjectTypeName = bo.Object.ObjectType.Name,
ObjectExternalId = bo.Object.ExternalId
})
.ToListAsync();
์คํ ์๊ฐ์ ์์๊ฐ 200-800ms์์ 2-20ms ๋ฑ์ผ๋ก ๊ฐ์ํ์ต๋๋ค. ์ฆ, ์์ญ ๋ฐฐ ๋ ๋นจ๋ผ์ก์ต๋๋ค.
๋ ํ๊ท ์ ์ผ๋ก ์ทจํ๋ฉด 350ms ๋์ 8ms๊ฐ ๋ฉ๋๋ค.
๋ช ๋ฐฑํ ์ด์ ์ผ๋ก๋ถํฐ ์ฐ๋ฆฌ๋ ๋ํ ๋ค์์ ์ป์ต๋๋ค:
- ๋ ์ ๋ถํ์ ์ ๋ฐ์ ์ธ ๊ฐ์,
- ์ฐจ๋จ ๊ฐ๋ฅ์ฑ์ด ํฌ๊ฒ ๊ฐ์ํฉ๋๋ค.
- ํ๊ท ์ฐจ๋จ ์๊ฐ์ ํ์ฉ ๊ฐ๋ฅํ ๊ฐ์ผ๋ก ์ค์ ๋๋ค.
์ถ๋ ฅ
๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ์ถ์ ์ต์ ํ ๋ฐ ๋ฏธ์ธ ์กฐ์ MS์ SQL ๋ฅผ ํตํด ๋งํฌ ํด๊ฒฐ๋ ์ ์๋ ๋ฌธ์ ๋ค.
์ด ์์ ์์๋ ์ธ์ฌํจ๊ณผ ์ผ๊ด์ฑ์ด ๋งค์ฐ ์ค์ํฉ๋๋ค.
ํ๋ก์ธ์ค ์์ ์:
- ์์ฒญ์ด ์๋ํ๋ ๋ฐ์ดํฐ(๊ฐ, ์ ํํ ๋ฐ์ดํฐ ์ ํ)๋ฅผ ํ์ธํด์ผ ํฉ๋๋ค.
- ์ด ๋ฐ์ดํฐ์ ์ ์ ํ ์ธ๋ฑ์ฑ์ ์ํํ์ญ์์ค.
- ํ ์ด๋ธ ๊ฐ ์กฐ์ธ ์กฐ๊ฑด์ด ์ฌ๋ฐ๋ฅธ์ง ํ์ธ
๋ค์ ์ต์ ํ ๋ฐ๋ณต์์๋ ๋ค์์ด ๋๋ฌ๋ฉ๋๋ค.
- ์์ฒญ์ ๊ธฐ๋ฐ์ผ๋ก ํ๊ณ ๊ธฐ๋ณธ ์์ฒญ ํํฐ๋ฅผ ์ ์ํฉ๋๋ค.
- ์ ์ฌํ ์ฟผ๋ฆฌ ๋ธ๋ก์ ๋ฐ๋ณตํ๊ณ ์กฐ๊ฑด์ ๊ต์ฐจ์ ์ ๋ถ์ํฉ๋๋ค.
- SSMS ๋๋ ๊ธฐํ GUI์์ SQL ์๋ฒ ์์ฒด์ ์ผ๋ก ์ต์ ํ SQL ์ฟผ๋ฆฌ (์ค๊ฐ ๋ฐ์ดํฐ ์ ์ฅ์ ํ ๋น, ์ด ์ ์ฅ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฐ๊ณผ ์ฟผ๋ฆฌ ์์ฑ(์ฌ๋ฌ ๊ฐ๊ฐ ์์ ์ ์์))
- ๋ง์ง๋ง ๋จ๊ณ์์ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ์ด๋ก ์ผ์ SQL ์ฟผ๋ฆฌ, ๊ตฌ์กฐ๊ฐ ์ฌ๊ฑด๋๊ณ ์์ต๋๋ค LINQ ์ฟผ๋ฆฌ
๊ฒฐ๊ณผ LINQ ์ฟผ๋ฆฌ ํ์ธ๋ ์ต์ ์ ๊ตฌ์กฐ์ ๊ตฌ์กฐ๊ฐ ๋์ผํด์ผ ํฉ๋๋ค. SQL ์ฟผ๋ฆฌ ํฌ์ธํธ 3๋ถํฐ.
๊ฐ์ฌ์ ๋ง
๋๋ฃ๋ค์๊ฒ ๊น์ ๊ฐ์ฌ๋ฅผ ๋๋ฆฝ๋๋ค
์ถ์ฒ : habr.com