C#.NET์—์„œ LINQ ์ฟผ๋ฆฌ๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•

์†Œ๊ฐœ

ะ’ ์ด ๊ธฐ์‚ฌ ๋ช‡ ๊ฐ€์ง€ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•์ด ๊ณ ๋ ค๋˜์—ˆ์Šต๋‹ˆ๋‹ค. LINQ ์ฟผ๋ฆฌ.
์—ฌ๊ธฐ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ด€๋ จ๋œ ์ฝ”๋“œ ์ตœ์ ํ™”์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค. LINQ ์ฟผ๋ฆฌ.

๊ทธ๊ฑฐ ์•Œ์•˜์–ด. ๋งํฌ(Language-Integrated Query)๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์ฟผ๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ„๋‹จํ•˜๊ณ  ํŽธ๋ฆฌํ•œ ์–ธ์–ด์ž…๋‹ˆ๋‹ค.

ะ LINQ์—์„œ SQL๋กœ DBMS์˜ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค. ์ด๋Š” ์„ ์–ธ์  ์–ธ์–ด๋ฅผ ํ†ตํ•ด ์ฟผ๋ฆฌ๊ฐ€ ๊ตฌ์„ฑ๋œ ํ›„ ๋‹ค์Œ์œผ๋กœ ๋ณ€ํ™˜๋˜๋Š” ๋ฐ์ดํ„ฐ ์ž‘์—…์„ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. SQL ์ฟผ๋ฆฌ ํ”Œ๋žซํผ์œผ๋กœ ์ „์†ก๋˜์–ด ์‹คํ–‰์„ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ DBMS๋Š” ๋‹ค์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. MS SQL ์„œ๋ฒ„.

๊ทธ๋Ÿฌ๋‚˜, LINQ ์ฟผ๋ฆฌ ์ตœ์ ์œผ๋กœ ์ž‘์„ฑ๋œ ๊ฒƒ์œผ๋กœ ๋ณ€ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค SQL ์ฟผ๋ฆฌ, ์ˆ™๋ จ๋œ DBA๊ฐ€ ์ตœ์ ํ™”์˜ ๋ชจ๋“  ๋‰˜์•™์Šค๋ฅผ ๋‹ด์•„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. SQL ์ฟผ๋ฆฌ:

  1. ์ตœ์ ์˜ ์—ฐ๊ฒฐ(JOIN) ๋ฐ ๊ฒฐ๊ณผ ํ•„ํ„ฐ๋ง(WHERE)
  2. ์—ฐ๊ฒฐ ๋ฐ ๊ทธ๋ฃน ์กฐ๊ฑด ์‚ฌ์šฉ ์‹œ ๋งŽ์€ ์ฐจ์ด
  3. ๊ต์ฒด ์กฐ๊ฑด์˜ ๋‹ค์–‘ํ•œ ๋ณ€ํ˜• IN ์— ์กด์žฌะธ ์•ˆ, <> ์ผœ์ง ์กด์žฌ
  4. ์ž„์‹œ ํ…Œ์ด๋ธ”, CTE, ํ…Œ์ด๋ธ” ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•œ ๊ฒฐ๊ณผ์˜ ์ค‘๊ฐ„ ์บ์‹ฑ
  5. ๋ฌธ์žฅ์˜ ์‚ฌ์šฉ (OPTION) ์ง€์นจ ๋ฐ ํ‘œ ํžŒํŠธ ํฌํ•จ ์„ธ์ดํ”„๊ฐ€๋“œ๊ฐ€ (...)
  6. ์„ ํƒ ์ค‘์— ์ค‘๋ณต๋œ ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ ์ค‘ ํ•˜๋‚˜๋กœ ์ธ๋ฑ์‹ฑ๋œ ๋ทฐ ์‚ฌ์šฉ

๊ฒฐ๊ณผ์˜ ์ฃผ์š” ์„ฑ๋Šฅ ๋ณ‘๋ชฉ ํ˜„์ƒ SQL ์ฟผ๋ฆฌ ์ปดํŒŒ์ผํ•  ๋•Œ LINQ ์ฟผ๋ฆฌ ์œ„์น˜ :

  1. ํ•˜๋‚˜์˜ ์š”์ฒญ์œผ๋กœ ์ „์ฒด ๋ฐ์ดํ„ฐ ์„ ํƒ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ํ†ตํ•ฉ
  2. ๋™์ผํ•œ ์ฝ”๋“œ ๋ธ”๋ก์„ ๋ณต์ œํ•˜์—ฌ ๊ถ๊ทน์ ์œผ๋กœ ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  3. ๋‹ค์ค‘ ๊ตฌ์„ฑ ์š”์†Œ ์กฐ๊ฑด ๊ทธ๋ฃน(๋…ผ๋ฆฌ์  "and" ๋ฐ "or") - ๋ฐ ะธ OR, ๋ณต์žกํ•œ ์กฐ๊ฑด์œผ๋กœ ๊ฒฐํ•ฉํ•˜๋ฉด ํ•„์š”ํ•œ ํ•„๋“œ์— ์ ํ•ฉํ•œ ๋น„ํด๋Ÿฌ์Šคํ„ฐํ˜• ์ธ๋ฑ์Šค๋ฅผ ๊ฐ–๋Š” ์ตœ์ ํ™” ํ”„๋กœ๊ทธ๋žจ์ด ๊ถ๊ทน์ ์œผ๋กœ ํด๋Ÿฌ์Šคํ„ฐํ˜• ์ธ๋ฑ์Šค์— ๋Œ€ํ•ด ์Šค์บ”ํ•˜๊ธฐ ์‹œ์ž‘ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค(์ธ๋ฑ์Šค ์Šค์บ”) ์กฐ๊ฑด ๊ทธ๋ฃน๋ณ„
  4. ํ•˜์œ„ ์ฟผ๋ฆฌ์˜ ๊นŠ์€ ์ค‘์ฒฉ์œผ๋กœ ์ธํ•ด ๊ตฌ๋ฌธ ๋ถ„์„์ด ๋งค์šฐ ๋ฌธ์ œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. SQL ๋ฌธ ๊ฐœ๋ฐœ์ž ์ธก์˜ ์ฟผ๋ฆฌ ๊ณ„ํš ๋ถ„์„ ๋ฐ DBA

์ตœ์ ํ™” ๋ฐฉ๋ฒ•

์ด์ œ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•์œผ๋กœ ์ง์ ‘ ์ด๋™ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1) ์ถ”๊ฐ€ ์ธ๋ฑ์‹ฑ

์ „์ฒด ์ฟผ๋ฆฌ๊ฐ€ ํ•˜๋‚˜ ๋˜๋Š” ๋‘ ๊ฐœ์˜ ๊ธฐ๋ณธ ํ…Œ์ด๋ธ”(์‘์šฉ ํ”„๋กœ๊ทธ๋žจ-์‚ฌ๋žŒ-์ž‘์—…)์„ ์ค‘์‹ฌ์œผ๋กœ ํ‘œ์ค€ ์กฐ๊ฑด ์ง‘ํ•ฉ(IsClosed, Canceled, Enabled, Status)์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์ถ•๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ ์„ ํƒ ํ…Œ์ด๋ธ”์˜ ํ•„ํ„ฐ๋ฅผ ๊ณ ๋ คํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ์‹๋ณ„๋œ ์ƒ˜ํ”Œ์— ๋Œ€ํ•ด ์ ์ ˆํ•œ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์ด ์†”๋ฃจ์…˜์€ ์ด๋Ÿฌํ•œ ํ•„๋“œ๋ฅผ ์„ ํƒํ•˜๋ฉด ๋ฐ˜ํ™˜๋˜๋Š” ์ฟผ๋ฆฌ ์ง‘ํ•ฉ์ด ํฌ๊ฒŒ ์ œํ•œ๋˜๋Š” ๊ฒฝ์šฐ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, 500000๊ฐœ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ™œ์„ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ 2000๊ฐœ๋ฟ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ ํƒ๋œ ์ƒ‰์ธ์ด ์šฐ๋ฆฌ๋ฅผ ๊ตฌํ•ด์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ธ๋ฑ์Šค ์Šค์บ” ํฐ ํ…Œ์ด๋ธ”์—์„œ ๋น„ํด๋Ÿฌ์Šคํ„ฐํ˜• ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ฟผ๋ฆฌ ๊ณ„ํš์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ฑฐ๋‚˜ ์‹œ์Šคํ…œ ๋ทฐ ํ†ต๊ณ„๋ฅผ ์ˆ˜์ง‘ํ•˜๋ผ๋Š” ํ”„๋กฌํ”„ํŠธ๋ฅผ ํ†ตํ•ด ์ธ๋ฑ์Šค ๋ถ€์กฑ์„ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. MS SQL ์„œ๋ฒ„:

  1. sys.dm_db_missing_index_groups
  2. sys.dm_db_missing_index_group_stats
  3. sys.dm_db_missing_index_details

๋ชจ๋“  ๋ทฐ ๋ฐ์ดํ„ฐ์—๋Š” ๊ณต๊ฐ„ ์ธ๋ฑ์Šค๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋ˆ„๋ฝ๋œ ์ธ๋ฑ์Šค์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ธ๋ฑ์Šค์™€ ์บ์‹ฑ์€ ์ž˜๋ชป ์ž‘์„ฑ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ธ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. LINQ ์ฟผ๋ฆฌ ะธ SQL ์ฟผ๋ฆฌ.

์‚ถ์˜ ๊ฐ€ํ˜นํ•œ ๊ด€ํ–‰์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ๊ธฐ์—…์ด ํŠน์ • ๋งˆ๊ฐ์ผ๊นŒ์ง€ ๋น„์ฆˆ๋‹ˆ์Šค ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ณผ๋„ํ•œ ์š”์ฒญ์€ ์บ์‹ฑ์„ ํ†ตํ•ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ ์ „์†ก๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž์—๊ฒŒ ํ•ญ์ƒ ์ตœ์‹  ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๋ฉฐ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์˜ ์‘๋‹ต์„ฑ์ด ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ์ˆ˜์ค€์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Š” ๋ถ€๋ถ„์ ์œผ๋กœ ์ •๋‹นํ™”๋ฉ๋‹ˆ๋‹ค.

์ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ ์‚ฌํ•ญ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์ง€์—ฐ์‹œ์ผœ ๊ถ๊ทน์ ์œผ๋กœ ์ •๋ณด ์‹œ์Šคํ…œ์˜ ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚ต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ถ”๊ฐ€ํ•  ํ•„์ˆ˜ ์ธ๋ฑ์Šค๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ณผ์ •์—์„œ ์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. MS์˜ SQL ๋‹ค์Œ ์กฐ๊ฑด์„ ํฌํ•จํ•˜์—ฌ ์ตœ์ ํ™”๊ฐ€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์œ ์‚ฌํ•œ ํ•„๋“œ ์ง‘ํ•ฉ์ด ํฌํ•จ๋œ ์ธ๋ฑ์Šค๊ฐ€ ์ด๋ฏธ ์žˆ๋Š” ๊ฒฝ์šฐ
  2. ์ธ๋ฑ์‹ฑ ์ œํ•œ์œผ๋กœ ์ธํ•ด ํ…Œ์ด๋ธ”์˜ ํ•„๋“œ๋ฅผ ์ธ๋ฑ์‹ฑํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ(์ž์„ธํžˆ ์„ค๋ช…) ์—ฌ๊ธฐ์—).

2) ์†์„ฑ์„ ํ•˜๋‚˜์˜ ์ƒˆ๋กœ์šด ์†์„ฑ์œผ๋กœ ๋ณ‘ํ•ฉ

๋•Œ๋กœ๋Š” ์กฐ๊ฑด ๊ทธ๋ฃน์˜ ๊ธฐ์ดˆ๋กœ ์‚ฌ์šฉ๋˜๋Š” ํ•œ ํ…Œ์ด๋ธ”์˜ ์ผ๋ถ€ ํ•„๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ์ƒˆ ํ•„๋“œ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์œ ํ˜•์ด ๋น„ํŠธ ๋˜๋Š” ์ •์ˆ˜์ธ ์ƒํƒœ ํ•„๋“œ์˜ ๊ฒฝ์šฐ ํŠนํžˆ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

์˜ˆ :

IsClosed = 0 AND ์ทจ์†Œ๋จ = 0 AND ํ™œ์„ฑํ™”๋จ = 0 ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค ์ƒํƒœ = 1.

์—ฌ๊ธฐ์— ์ด๋Ÿฌํ•œ ์ƒํƒœ๊ฐ€ ํ…Œ์ด๋ธ”์— ์ฑ„์›Œ์ง€๋„๋ก ์ •์ˆ˜ ์ƒํƒœ ์†์„ฑ์ด ๋„์ž…๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ์ด ์ƒˆ ์†์„ฑ์ด ์ƒ‰์ธํ™”๋ฉ๋‹ˆ๋‹ค.

๋ถˆํ•„์š”ํ•œ ๊ณ„์‚ฐ ์—†์ด ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Š” ์„ฑ๋Šฅ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๊ทผ๋ณธ์ ์ธ ํ•ด๊ฒฐ์ฑ…์ž…๋‹ˆ๋‹ค.

3) ๋ทฐ์˜ ๊ตฌ์ฒดํ™”

๋ถˆํ–‰ํ•˜๊ฒŒ๋„, LINQ ์ฟผ๋ฆฌ ์ž„์‹œ ํ…Œ์ด๋ธ”, CTE ๋ฐ ํ…Œ์ด๋ธ” ๋ณ€์ˆ˜๋Š” ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด ๊ฒฝ์šฐ๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•, ์ฆ‰ ์ธ๋ฑ์‹ฑ๋œ ๋ทฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์กฐ๊ฑด ๊ทธ๋ฃน(์œ„ ์˜ˆ) IsClosed = 0 AND ์ทจ์†Œ๋จ = 0 AND ํ™œ์„ฑํ™”๋จ = 0 (๋˜๋Š” ๊ธฐํƒ€ ์œ ์‚ฌํ•œ ์กฐ๊ฑด ์ง‘ํ•ฉ)์€ ์ธ๋ฑ์‹ฑ๋œ ๋ทฐ์—์„œ ์‚ฌ์šฉํ•˜์—ฌ ํฐ ์ง‘ํ•ฉ์—์„œ ์ž‘์€ ๋ฐ์ดํ„ฐ ์กฐ๊ฐ์„ ์บ์‹ฑํ•˜๋Š” ์ข‹์€ ์˜ต์…˜์ด ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋ทฐ๋ฅผ ๊ตฌ์ฒดํ™”ํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ œํ•œ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ํ•˜์œ„ ์ฟผ๋ฆฌ, ์ ˆ ์‚ฌ์šฉ ์กด์žฌ ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ต์ฒดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. JOIN
  2. ๋„ˆ๋Š” ๋ฌธ์žฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค UNION, UNION ALL, ์˜ˆ์™ธ, ๊ต์ฐจ
  3. ํ…Œ์ด๋ธ” ํžŒํŠธ์™€ ์ ˆ์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. OPTION
  4. ์‚ฌ์ดํด ์ž‘์—… ๊ฐ€๋Šฅ์„ฑ ์—†์Œ
  5. ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ ํ•˜๋‚˜์˜ ๋ทฐ์— ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ธ๋ฑ์‹ฑ๋œ ๋ทฐ ์‚ฌ์šฉ์˜ ์‹ค์ œ ์ด์ ์€ ์‹ค์ œ๋กœ ์ธ๋ฑ์‹ฑํ•ด์•ผ๋งŒ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋ทฐ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ด๋Ÿฌํ•œ ์ธ๋ฑ์Šค๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํฌํ•จ(ํ™•์žฅ ์—†์Œ).

๋ถ€ํ„ฐ LINQ ์ฟผ๋ฆฌ ํ…Œ์ด๋ธ” ํžŒํŠธ๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ๋‹ค์Œ ํ˜•์‹์˜ "๋ž˜ํผ"๋ผ๋Š” ๋˜ ๋‹ค๋ฅธ ํ‘œํ˜„์„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

CREATE VIEW ะ˜ะœะฏ_ะฟั€ะตะดัั‚ะฐะฒะปะตะฝะธั AS SELECT * FROM MAT_VIEW WITH (NOEXPAND);

4) ํ…Œ์ด๋ธ” ํ•จ์ˆ˜ ์‚ฌ์šฉํ•˜๊ธฐ

์ข…์ข… LINQ ์ฟผ๋ฆฌ ๋ณต์žกํ•œ ๊ตฌ์กฐ์˜ ๋ทฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํฐ ํ•˜์œ„ ์ฟผ๋ฆฌ ๋ธ”๋ก ๋˜๋Š” ๋ธ”๋ก์€ ๋งค์šฐ ๋ณต์žกํ•˜๊ณ  ์ตœ์ ์ด ์•„๋‹Œ ์‹คํ–‰ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง„ ์ตœ์ข… ์ฟผ๋ฆฌ๋ฅผ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ด๋ธ” ํ•จ์ˆ˜ ์‚ฌ์šฉ์˜ ์ฃผ์š” ์ด์  LINQ ์ฟผ๋ฆฌ:

  1. ๋ทฐ์˜ ๊ฒฝ์šฐ์™€ ๊ฐ™์ด ๊ฐ์ฒด๋กœ ์‚ฌ์šฉ ๋ฐ ์ง€์ •๋˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์ง€๋งŒ ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜ ์„ธํŠธ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ํ•จ์ˆ˜์—์„œ(@param1, @param2 ...)
    ๊ฒฐ๊ณผ์ ์œผ๋กœ ์œ ์—ฐํ•œ ๋ฐ์ดํ„ฐ ์ƒ˜ํ”Œ๋ง์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  2. ํ…Œ์ด๋ธ” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์œ„์—์„œ ์„ค๋ช…ํ•œ ์ธ๋ฑ์‹ฑ๋œ ๋ทฐ์˜ ๊ฒฝ์šฐ์ฒ˜๋Ÿผ ๊ฐ•๋ ฅํ•œ ์ œํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค.
    1. ํ…Œ์ด๋ธ” ํžŒํŠธ:
      ๋ฅผ ํ†ตํ•ด ๋งํฌ ์ฟผ๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ธ๋ฑ์Šค๋ฅผ ์ง€์ •ํ•˜๊ณ  ๋ฐ์ดํ„ฐ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
      ํ•˜์ง€๋งŒ ํ•จ์ˆ˜์—๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
      ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ธ๋ฑ์Šค ๋ฐ ๋ฐ์ดํ„ฐ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ ์ž‘์—…์— ๋Œ€ํ•œ ๊ทœ์น™์ด ์ •์˜๋˜๋Š” ์ƒ๋‹นํžˆ ์ผ์ •ํ•œ ์‹คํ–‰ ์ฟผ๋ฆฌ ๊ณ„ํš์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    2. ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ธ๋ฑ์‹ฑ๋œ ๋ทฐ์™€ ๋น„๊ตํ•˜์—ฌ ๋‹ค์Œ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      • ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ์ƒ˜ํ”Œ๋ง ๋…ผ๋ฆฌ(๋ฃจํ”„ ์‚ฌ์šฉ ์‹œ์—๋„)
      • ๋‹ค์–‘ํ•œ ํ…Œ์ด๋ธ”์—์„œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ
      • ์˜ ์‚ฌ์šฉ UNION ะธ ์กด์žฌ

  3. ์ œ์•ˆ OPTION ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•  ๋•Œ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ต์…˜(MAXDOP N), ์ฟผ๋ฆฌ ์‹คํ–‰ ๊ณ„ํš์˜ ์ˆœ์„œ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:
    • ์ฟผ๋ฆฌ ๊ณ„ํš์„ ๊ฐ•์ œ๋กœ ๋‹ค์‹œ ์ƒ์„ฑํ•˜๋„๋ก ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ต์…˜(์žฌ์ปดํŒŒ์ผ)
    • ์ฟผ๋ฆฌ ๊ณ„ํš์ด ์ฟผ๋ฆฌ์— ์ง€์ •๋œ ์กฐ์ธ ์ˆœ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ฐ•์ œํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ต์…˜(๊ฐ•์ œ ๋ช…๋ น)

    ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ OPTION ์„ค๋ช… ์—ฌ๊ธฐ์—.

  4. ๊ฐ€์žฅ ์ข๊ณ  ๊ฐ€์žฅ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ์กฐ๊ฐ ์‚ฌ์šฉ:
    ์ธ๋ฑ์‹ฑ๋œ ๋ทฐ์˜ ๊ฒฝ์šฐ์ฒ˜๋Ÿผ ์บ์‹œ์— ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ์„ธํŠธ๋ฅผ ์ €์žฅํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉฐ ์บ์‹œ์—์„œ ์—ฌ์ „ํžˆ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ณ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํ•„ํ„ฐ๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    ์˜ˆ๋ฅผ ๋“ค์–ด ํ•„ํ„ฐ๊ฐ€ ์žˆ๋Š” ํ…Œ์ด๋ธ”์ด ์žˆ์Šต๋‹ˆ๋‹ค. 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๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

๋ช…๋ฐฑํ•œ ์ด์ ์œผ๋กœ๋ถ€ํ„ฐ ์šฐ๋ฆฌ๋Š” ๋˜ํ•œ ๋‹ค์Œ์„ ์–ป์Šต๋‹ˆ๋‹ค:

  1. ๋…์„œ ๋ถ€ํ•˜์˜ ์ „๋ฐ˜์ ์ธ ๊ฐ์†Œ,
  2. ์ฐจ๋‹จ ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๊ฒŒ ๊ฐ์†Œํ•ฉ๋‹ˆ๋‹ค.
  3. ํ‰๊ท  ์ฐจ๋‹จ ์‹œ๊ฐ„์„ ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฐ’์œผ๋กœ ์ค„์ž…๋‹ˆ๋‹ค.

์ถœ๋ ฅ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ˜ธ์ถœ์˜ ์ตœ์ ํ™” ๋ฐ ๋ฏธ์„ธ ์กฐ์ • MS์˜ SQL ๋ฅผ ํ†ตํ•ด ๋งํฌ ํ•ด๊ฒฐ๋  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋‹ค.

์ด ์ž‘์—…์—์„œ๋Š” ์„ธ์‹ฌํ•จ๊ณผ ์ผ๊ด€์„ฑ์ด ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์„ธ์Šค ์‹œ์ž‘ ์‹œ:

  1. ์š”์ฒญ์ด ์ž‘๋™ํ•˜๋Š” ๋ฐ์ดํ„ฐ(๊ฐ’, ์„ ํƒํ•œ ๋ฐ์ดํ„ฐ ์œ ํ˜•)๋ฅผ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  2. ์ด ๋ฐ์ดํ„ฐ์˜ ์ ์ ˆํ•œ ์ธ๋ฑ์‹ฑ์„ ์ˆ˜ํ–‰ํ•˜์‹ญ์‹œ์˜ค.
  3. ํ…Œ์ด๋ธ” ๊ฐ„ ์กฐ์ธ ์กฐ๊ฑด์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธ

๋‹ค์Œ ์ตœ์ ํ™” ๋ฐ˜๋ณต์—์„œ๋Š” ๋‹ค์Œ์ด ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค.

  1. ์š”์ฒญ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๊ณ  ๊ธฐ๋ณธ ์š”์ฒญ ํ•„ํ„ฐ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  2. ์œ ์‚ฌํ•œ ์ฟผ๋ฆฌ ๋ธ”๋ก์„ ๋ฐ˜๋ณตํ•˜๊ณ  ์กฐ๊ฑด์˜ ๊ต์ฐจ์ ์„ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค.
  3. SSMS ๋˜๋Š” ๊ธฐํƒ€ GUI์—์„œ SQL ์„œ๋ฒ„ ์ž์ฒด์ ์œผ๋กœ ์ตœ์ ํ™” SQL ์ฟผ๋ฆฌ (์ค‘๊ฐ„ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ ํ• ๋‹น, ์ด ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ ์ฟผ๋ฆฌ ์ž‘์„ฑ(์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Œ))
  4. ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„์—์„œ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ์ดˆ๋กœ ์‚ผ์•„ SQL ์ฟผ๋ฆฌ, ๊ตฌ์กฐ๊ฐ€ ์žฌ๊ฑด๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค LINQ ์ฟผ๋ฆฌ

๊ฒฐ๊ณผ LINQ ์ฟผ๋ฆฌ ํ™•์ธ๋œ ์ตœ์ ์˜ ๊ตฌ์กฐ์™€ ๊ตฌ์กฐ๊ฐ€ ๋™์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. SQL ์ฟผ๋ฆฌ ํฌ์ธํŠธ 3๋ถ€ํ„ฐ.

๊ฐ์‚ฌ์˜ ๋ง

๋™๋ฃŒ๋“ค์—๊ฒŒ ๊นŠ์€ ๊ฐ์‚ฌ๋ฅผ ๋“œ๋ฆฝ๋‹ˆ๋‹ค ์ง์—… ๋ณด์„ ะธ alex_ozr ํšŒ์‚ฌ์—์„œ ํฌ๋ฅด ํ‹ฐ์Šค ์ด ์ž๋ฃŒ๋ฅผ ์ค€๋น„ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์š”์ฒญํ–ˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€