ΠœΠ΅Ρ‚ΠΎΠ΄ΠΈ Π·Π° оптимизация Π½Π° LINQ заявки Π² C#.NET

Π’ΡŠΠ²Π΅Π΄Π΅Π½ΠΈΠ΅

Π’ Ρ‚Π°Π·ΠΈ статия Π Π°Π·Π³Π»Π΅ΠΆΠ΄Π°Π»ΠΈ са някои ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π·Π° оптимизация заявки Π½Π° LINQ.
Π’ΡƒΠΊ Ρ‰Π΅ прСдставим ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈ Π·Π° оптимизация Π½Π° ΠΊΠΎΠ΄Π°, ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ с заявкитС Π½Π° LINQ.

Π˜Π·Π²Π΅ΡΡ‚Π½ΠΎ Π΅, Ρ‡Π΅ LINQ(Language-Integrated Query) β€” Ρ‚ΠΎΠ²Π° Π΅ прост ΠΈ ΡƒΠ΄ΠΎΠ±Π΅Π½ Π΅Π·ΠΈΠΊ Π·Π° заявки към ΠΈΠ·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ Π½Π° Π΄Π°Π½Π½ΠΈ.

А LINQ to SQL Π΅ тСхнология Π·Π° Π΄ΠΎΡΡ‚ΡŠΠΏ Π΄ΠΎ Π΄Π°Π½Π½ΠΈ Π² Π‘Π£Π‘Π”. Π’ΠΎΠ²Π° Π΅ ΠΌΠΎΡ‰Π΅Π½ инструмСнт Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Π΄Π°Π½Π½ΠΈ, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ Ρ‡Ρ€Π΅Π· Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π΅Π½ Π΅Π·ΠΈΠΊ сС конструират заявки, ΠΊΠΎΠΈΡ‚ΠΎ слСд Ρ‚ΠΎΠ²Π° Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°Π½ΠΈ Π² SQL-заявки ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° ΠΈ ΠΈΠ·ΠΏΡ€Π°Ρ‚Π΅Π½ΠΈ Π½Π° ΡΡŠΡ€Π²ΡŠΡ€Π° Π½Π° Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π·Π° изпълнСниС. Π’ нашия случай Ρ‰Π΅ Ρ€Π°Π·Π±ΠΈΡ€Π°ΠΌΠ΅ ΠΏΠΎΠ΄ Π‘Π£Π‘Π” MS SQL Server.

Но заявки Π½Π° LINQ Π½Π΅ сС ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°Ρ‚ Π² ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»Π½ΠΎ написани SQL-заявки, ΠΊΠΎΠΈΡ‚ΠΎ Π±ΠΈ могъл Π΄Π° напишС ΠΎΠΏΠΈΡ‚Π΅Π½ DBA с всички нюанси Π½Π° оптимизацията SQL-заявки:

  1. ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»Π½ΠΈ съСдинСния (JOIN) ΠΈ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈ (WHERE)
  2. мноТСство нюанси Π² ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° съСдинСния ΠΈ Π³Ρ€ΡƒΠΏΠΎΠ²ΠΈ условия
  3. мноТСство Π²Π°Ρ€ΠΈΠ°Ρ†ΠΈΠΈ ΠΏΡ€ΠΈ замяната Π½Π° условия IN Π½Π° EXISTSΠΈ NOT IN, Π½Π° EXISTS
  4. ΠΏΡ€ΠΎΠΌΠ΅ΠΆΠ΄ΡƒΡ‚ΡŠΡ‡Π½ΠΎ ΠΊΠ΅ΡˆΠΈΡ€Π°Π½Π΅ Π½Π° Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈΡ‚Π΅ Ρ‡Ρ€Π΅Π· Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ, CTE, Ρ‚Π°Π±Π»ΠΈΡ†ΠΎΠ²ΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ
  5. ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ (OPTION) с указания ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†ΠΎΠ²ΠΈ Ρ…ΠΈΠ½Ρ‚ΠΎΠ²Π΅ WITH (…)
  6. ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° индСксируСми прСдставлСния, ΠΊΠ°Ρ‚ΠΎ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ срСдствата Π·Π° избавянС ΠΎΡ‚ излишни чСтСния Π½Π° Π΄Π°Π½Π½ΠΈ ΠΏΡ€ΠΈ ΠΈΠ·Π²Π»ΠΈΡ‡Π°Π½Π΅

ΠžΡΠ½ΠΎΠ²Π½ΠΈΡ‚Π΅ ΡƒΠ·ΠΊΠΈ мСста Π½Π° производитСлността ΠΏΡ€ΠΈ компилация SQL-заявки консолидиранС Π½Π° цСлия ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ Π·Π° ΠΈΠ·Π²Π»ΠΈΡ‡Π°Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ Π² Π΅Π΄Π½Π° заявка заявки Π½Π° LINQ са:

  1. Π΄ΡƒΠ±Π»ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½ΠΈ Π±Π»ΠΎΠΊΠΎΠ²Π΅ ΠΊΠΎΠ΄, ΠΊΠΎΠ΅Ρ‚ΠΎ Π²ΠΎΠ΄ΠΈ Π΄ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΈ Π½Π΅Π½ΡƒΠΆΠ½ΠΈ чСтСния Π½Π° Π΄Π°Π½Π½ΠΈ
  2. Π³Ρ€ΡƒΠΏΠΈ ΠΎΡ‚ слоТни условия (логичСски β€žΠΈβ€œ ΠΈ β€žΠΈΠ»ΠΈβ€œ) β€”
  3. OR И ΠΈ , ΡΠ²ΡŠΡ€Π·Π²Π°ΠΉΠΊΠΈ сС Π² слоТни условия, Π²ΠΎΠ΄ΠΈ Π΄ΠΎ Ρ‚ΠΎΠ²Π°, Ρ‡Π΅ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ‚ΠΎΡ€ΡŠΡ‚, Ρ€Π°Π·ΠΏΠΎΠ»Π°Π³Π°Ρ‰ с подходящи нСкластСризирани индСкси ΠΏΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈΡ‚Π΅ ΠΏΠΎΠ»Π΅Ρ‚Π°, Π² ΠΊΡ€Π°ΠΉΠ½Π° смСтка всС ΠΏΠ°ΠΊ Π·Π°ΠΏΠΎΡ‡Π²Π° Π΄Π° ΠΏΡ€Π°Π²ΠΈ сканиранС ΠΏΠΎ кластСрСн индСкс (INDEX SCAN) ΠΏΠΎ Π³Ρ€ΡƒΠΏΠΈ ΡƒΡΠ»ΠΎΠ²ΠΈΡΠ΄ΡŠΠ»Π±ΠΎΠΊΠ°Ρ‚Π° влоТСност Π½Π° подзаявки ΠΏΡ€Π°Π²ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅
  4. SQL-инструкции ΠΈ Π°Π½Π°Π»ΠΈΠ· Π½Π° ΠΏΠ»Π°Π½Π° Π·Π° заявки ΠΎΡ‚ страна Π½Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈΡ‚Π΅ ΠΈ DBA ΠœΠ΅Ρ‚ΠΎΠ΄ΠΈ Π·Π° оптимизация

Π‘Π΅Π³Π° Ρ‰Π΅ ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ΠΌ Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ към ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΡ‚Π΅ Π·Π° оптимизация.

1) Π”ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΎ индСксиранС

1) Π”ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΎ индСксиранС

Най-Π΄ΠΎΠ±Ρ€Π΅ Π΅ Π΄Π° сС Ρ€Π°Π·Π³Π»Π΅ΠΆΠ΄Π°Ρ‚ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ‚Π΅ Π½Π° основнитС Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ Π·Π° заявки, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΌΠ½ΠΎΠ³ΠΎ чСсто цялото Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ сС ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π° ΠΎΠΊΠΎΠ»ΠΎ Π΅Π΄Π½Π°-Π΄Π²Π΅ основни Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ (заявки-личности-ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ) ΠΈ с стандартСн Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ условия (IsClosed, Canceled, Enabled, Status). Π’Π°ΠΆΠ½ΠΎ Π΅ Π·Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°Π½ΠΈΡ‚Π΅ сСлСкции Π΄Π° сС ΡΡŠΠ·Π΄Π°Π΄Π°Ρ‚ ΡΡŠΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π°Ρ‰ΠΈ индСкси.

Π’ΠΎΠ²Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π΅ Ρ€Π°Π·ΡƒΠΌΠ½ΠΎ, ΠΊΠΎΠ³Π°Ρ‚ΠΎ сСлСкцията ΠΏΠΎ Ρ‚Π΅Π·ΠΈ ΠΏΠΎΠ»Π΅Ρ‚Π° Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π°Π²Π° Π²Ρ€ΡŠΡ‰Π°Π½ΠΎΡ‚ΠΎ мноТСство ΠΎΡ‚ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ.

НапримСр, ΠΈΠΌΠ°ΠΌΠ΅ 500000 заявки. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, Π°ΠΊΡ‚ΠΈΠ²Π½ΠΈΡ‚Π΅ заявки са само 2000 записа. Π’ Ρ‚ΠΎΠ·ΠΈ случай, ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ подбраният индСкс Ρ‰Π΅ Π½ΠΈ освободи ΠΎΡ‚ ) ΠΏΠΎ Π³Ρ€ΡƒΠΏΠΈ условия голямата Ρ‚Π°Π±Π»ΠΈΡ†Π° ΠΈ Ρ‰Π΅ Π½ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈ Π±ΡŠΡ€Π·ΠΎ Π΄Π° ΠΈΠ·Π²Π»Π΅Ρ‡Π΅ΠΌ Π΄Π°Π½Π½ΠΈ Ρ‡Ρ€Π΅Π· нСкластСризиран индСкс.

Π‘ΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ°, липсата Π½Π° индСкси ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°Π½Π° Ρ‡Ρ€Π΅Π· подсказки ΠΎΡ‚ Π°Π½Π°Π»ΠΈΠ·Π° Π½Π° ΠΏΠ»Π°Π½Π° Π½Π° запитванията ΠΈΠ»ΠΈ Ρ‡Ρ€Π΅Π· ΡΡŠΠ±ΠΈΡ€Π°Π½Π΅ Π½Π° статистики ΠΎΡ‚ систСмнитС прСдставлСния MS SQL Server:

  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 И Canceled = 0 И Enabled = 0 сС замСня с Status = 1.

Π’ΡƒΠΊ сС въвСТда цяло число Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ Status, осигурСно Ρ‡Ρ€Π΅Π· попълванС Π½Π° Ρ‚Π΅Π·ΠΈ статути Π² Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π°. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° индСксиранС Π½Π° Ρ‚ΠΎΠ·ΠΈ Π½ΠΎΠ² Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚.

Π’ΠΎΠ²Π° Π΅ Ρ„ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚Π°Π»Π½ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π½Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° с производитСлността, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Π½ΠΈΠ΅ ΠΈΠ·Π²ΠΈΠΊΠ²Π°ΠΌΠ΅ Π΄Π°Π½Π½ΠΈ Π±Π΅Π· излишни изчислСния.

3) ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° прСдставлСниС

Π—Π° съТалСниС, Π² LINQ запитванията Π½Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ, CTE ΠΈ Ρ‚Π°Π±Π»ΠΈΡ‡Π½ΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ.

ΠžΠ±Π°Ρ‡Π΅, ΠΈΠΌΠ° ΠΈ Π΄Ρ€ΡƒΠ³ Π½Π°Ρ‡ΠΈΠ½ Π·Π° оптимизация Π² Ρ‚ΠΎΠ·ΠΈ случай β€” индСксируСми прСдставлСния.

Π“Ρ€ΡƒΠΏΠ° условия (ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΏΠΎ-Π³ΠΎΡ€Π΅) IsClosed = 0 И Canceled = 0 И Enabled = 0 (ΠΈΠ»ΠΈ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΈ условия) Π΅ Π΄ΠΎΠ±Ρ€ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π² индСксируСмо прСдставлСниС, ΠΊΠ΅ΡˆΠΈΡ€Π°ΠΉΠΊΠΈ малък ΠΈΠ·Ρ€Π΅Π· ΠΎΡ‚ Π΄Π°Π½Π½ΠΈ ΠΎΡ‚ голямо мноТСство.

Но ΠΈΠΌΠ° Ρ€Π΅Π΄ΠΈΡ†Π° ограничСния ΠΏΡ€ΠΈ матСриализацията Π½Π° прСдставлСниСто:

  1. ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° подзапитвания, прСдлоТСния EXISTS трябва Π΄Π° сС замСнят с ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° JOIN
  2. Π½Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ прСдлоТСния UNION, UNION ALL, EXCEPTION, INTERSECT
  3. Π½Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Ρ‚Π°Π±Π»ΠΈΡ‡Π½ΠΈ подсказки ΠΈ прСдлоТСния OPTION
  4. няма Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Ρ†ΠΈΠΊΠ»ΠΈ
  5. нСвъзмоТно Π΅ Π΄Π° сС ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Ρ‚ Π΄Π°Π½Π½ΠΈ Π² Π΅Π΄Π½ΠΎ прСдставлСниС ΠΎΡ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ

Π’Π°ΠΆΠ½ΠΎ Π΅ Π΄Π° сС ΠΏΠΎΠΌΠ½ΠΈ, Ρ‡Π΅ Ρ€Π΅Π°Π»Π½Π°Ρ‚Π° ΠΏΠΎΠ»Π·Π° ΠΎΡ‚ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° индСксируСмо прСдставлСниС ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π° Π²ΡΡŠΡ‰Π½ΠΎΡΡ‚ само ΠΏΡ€ΠΈ Π½Π΅Π³ΠΎΠ²ΠΎΡ‚ΠΎ индСксиранС.

Но ΠΏΡ€ΠΈ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° прСдставлСниСто Ρ‚Π΅Π·ΠΈ индСкси ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚, Π° Π·Π° явното ΠΈΠΌ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ трябва Π΄Π° сС посочи WITH (NOEXPAND).

Въй ΠΊΠ°Ρ‚ΠΎ Π² LINQ запитванията Π½Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС опрСдСлят Ρ‚Π°Π±Π»ΠΈΡ‡Π½ΠΈ подсказки, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ сС Π½Π°Π»Π°Π³Π° Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ ΠΎΡ‰Π΅ Π΅Π΄Π½ΠΎ прСдставлСниС β€” 'ΠΎΠ±Π²ΠΈΠ²ΠΊΠ°' ΠΎΡ‚ слСдния Π²ΠΈΠ΄:

CREATE VIEW Π˜ΠœΠ•_прСдставлСния AS SELECT * FROM MAT_VIEW WITH (NOEXPAND);

4) ИзползванС Π½Π° Ρ‚Π°Π±Π»ΠΈΡ‡Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

ЧСсто Π² LINQ запитванията Π³ΠΎΠ»Π΅ΠΌΠΈ Π±Π»ΠΎΠΊΠΎΠ²Π΅ подзапитвания ΠΈΠ»ΠΈ Π±Π»ΠΎΠΊΠΎΠ²Π΅, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ΠΈ прСдставлСния със слоТна структура, оформят ΠΊΡ€Π°ΠΉΠ½ΠΎ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ с ΠΌΠ½ΠΎΠ³ΠΎ слоТна ΠΈ Π½Π΅ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»Π½Π° структура Π½Π° изпълнСниС.

ΠžΡΠ½ΠΎΠ²Π½ΠΈΡ‚Π΅ прСдимства Π½Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Ρ‚Π°Π±Π»ΠΈΡ‡Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² LINQ запитванията:

  1. Π’ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚Ρ‚Π°, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ Π² случая с прСдставлСнията, Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΈ Π΄Π° сС ΡƒΠΊΠ°Π·Π²Π° ΠΊΠ°Ρ‚ΠΎ ΠΎΠ±Π΅ΠΊΡ‚, Π½ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΡ€Π΅Π΄Π°Π΄Π΅ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ входящи ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ:
    FROM FUNCTION(@param1, @param2 …)
    Π² ΠΊΡ€Π°ΠΉΠ½Π° смСтка ΠΌΠΎΠΆΠ΅ Π΄Π° сС постигнС гъвкаво ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ Π½Π° Π΄Π°Π½Π½ΠΈ
  2. Π’ случай Π½Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Ρ‚Π°Π±Π»ΠΈΡ‡Π½Π° функция няма Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° строги ограничСния, ΠΊΠ°ΠΊΡ‚ΠΎ Π² случая с индСксируСмитС прСдставлСния, описани ΠΏΠΎ-Π³ΠΎΡ€Π΅:
    1. Π’Π°Π±Π»ΠΈΡ‡Π½ΠΈ подсказки:
      Ρ‡Ρ€Π΅Π· LINQ НСвъзмоТно Π΅ Π΄Π° сС Π·Π°Π΄Π°Π²Π°Ρ‚ ΠΊΠΎΠΉ индСкси Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ ΠΈ Π΄Π° сС опрСдСля Π½ΠΈΠ²ΠΎΡ‚ΠΎ Π½Π° изолация Π½Π° Π΄Π°Π½Π½ΠΈΡ‚Π΅ ΠΏΡ€ΠΈ заявка.
      Но Π² функцията Ρ‚Π΅Π·ΠΈ Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΠΈ са Π½Π°Π»ΠΈΡ‡Π½ΠΈ.
      Π‘ функцията ΠΌΠΎΠΆΠ΅ Π΄Π° сС постигнС Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ постоянСн ΠΏΠ»Π°Π½ Π·Π° изпълнСниС Π½Π° заявкитС, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ са ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π°Ρ‚Π° Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с индСкситС ΠΈ Π½ΠΈΠ²Π°Ρ‚Π° Π½Π° изолация Π½Π° Π΄Π°Π½Π½ΠΈΡ‚Π΅.
    2. Π˜Π·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° функция позволява, Π² сравнСниС с индСксируСмитС прСдставлСния, Π΄Π° сС ΠΏΠΎΠ»ΡƒΡ‡ΠΈ:
      • слоТна Π»ΠΎΠ³ΠΈΠΊΠ° Π·Π° ΠΈΠ·Π²Π»ΠΈΡ‡Π°Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ (Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Ρ†ΠΈΠΊΠ»ΠΈ)
      • ΠΈΠ·Π²Π»ΠΈΡ‡Π°Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ ΠΎΡ‚ мноТСство Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ
      • ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ UNION ΠΈ EXISTS

  3. ΠŸΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ OPTION ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, ΠΊΠΎΠ³Π°Ρ‚ΠΎ трябва Π΄Π° осигурим ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° ΠΏΠ°Ρ€Π°Π»Π΅Π»ΠΈΠ·ΠΌΠ° OPTION(MAXDOP N), ΠΏΠΎΡ€ΡΠ΄ΡŠΠΊΠ° Π½Π° ΠΏΠ»Π°Π½Π° Π·Π° изпълнСниС Π½Π° заявката. НапримСр:
    • ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π·Π°Π΄Π°Π΄Π΅ ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»Π½ΠΎ Π²ΡŠΠ·ΡΡ‚Π°Π½ΠΎΠ²ΡΠ²Π°Π½Π΅ Π½Π° ΠΏΠ»Π°Π½Π° Π·Π° заявка OPTION (RECOMPILE)
    • ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π·Π°Π΄Π°Π΄Π΅ нСобходимостта ΠΎΡ‚ ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ΠΏΠ»Π°Π½Π° Π·Π° заявка Π² Ρ€Π΅Π΄Π° Π½Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅, посочСн Π² заявката OPTION (FORCE ORDER)

    По-ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ Π·Π° OPTION Π΅ описано Ρ‚ΡƒΠΊ..

  4. Π˜Π·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π½Π°ΠΉ-тСсния ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ срСз ΠΎΡ‚ Π΄Π°Π½Π½ΠΈ:
    Няма Π½ΡƒΠΆΠ΄Π° Π΄Π° сС ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Ρ‚ Π³ΠΎΠ»Π΅ΠΌΠΈ Π½Π°Π±ΠΎΡ€ΠΈ ΠΎΡ‚ Π΄Π°Π½Π½ΠΈ Π² кСша (ΠΊΠ°ΠΊΡ‚ΠΎ Π² случая с индСксируСмитС прСдставлСния), ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ ΡΡŠΡ‰ΠΎ трябва Π΄Π° сС Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Ρ‚ Π΄Π°Π½Π½ΠΈ ΠΏΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€.
    НапримСр, ΠΈΠΌΠ° Ρ‚Π°Π±Π»ΠΈΡ†Π°, Π·Π° която Π·Π° Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ WHERE сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Ρ‚Ρ€ΠΈ ΠΏΠΎΠ»Π΅Ρ‚Π° (a, b, c).

    Условно Π·Π° всички заявки ΠΈΠΌΠ° постоянно условиС a = 0 ΠΈ b = 0.

    ΠžΠ±Π°Ρ‡Π΅, заявката към ΠΏΠΎΠ»Π΅Ρ‚ΠΎ с Π΅ ΠΏΠΎ-Π²Π°Ρ€ΠΈΠ°Ρ‚ΠΈΠ²Π½Π°.

    НСка условиСто a = 0 ΠΈ b = 0 дСйствитСлно Π΄Π° Π½ΠΈ ΠΏΠΎΠΌΠΎΠ³Π½Π΅ Π΄Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠΌ нСобходимия ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ Π½Π°Π±ΠΎΡ€ Π΄ΠΎ хиляди записи, Π½ΠΎ условиСто ΠΏΠΎ с Π½ΠΈ стСснява Ρ€Π°Π·Ρ€Π΅Π·Π° Π΄ΠΎ сто записа.

    Π’ΡƒΠΊ Ρ‚Π°Π±Π»ΠΈΡ‡Π½Π°Ρ‚Π° функция ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΎΠΊΠ°ΠΆΠ΅ ΠΏΠΎ-ΠΈΠ·Π³ΠΎΠ΄Π΅Π½ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚.

    Π‘ΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° Ρ‚Π°Π±Π»ΠΈΡ‡Π½Π°Ρ‚Π° функция Π΅ ΠΏΠΎ-прСдсказуСма ΠΈ постоянна ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° изпълнСниС.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ΠΈ

НСка Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° рСализация Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Π±Π°Π·Π°Ρ‚Π° ΠΎΡ‚ Π΄Π°Π½Π½ΠΈ Questions.

Има заявка SELECT, ΡΠ²ΡŠΡ€Π·Π²Π°Ρ‰Π° Π² сСбС си няколко Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰Π° Π΅Π΄Π½ΠΎ прСдставлСниС (OperativeQuestions), Π² ΠΊΠΎΠ΅Ρ‚ΠΎ сС провСрява ΠΏΠΎ email принадлСТността (Ρ‡Ρ€Π΅Π· EXISTS) към «Активни заявки»([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 Π΅ ΠΎΠΊΠΎΠ»ΠΎ дСсСт хиляди записа.

ΠžΡΠ½ΠΎΠ²Π½ΠΈΡΡ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π½Π° Ρ‚ΠΎΠ·ΠΈ Π·Π°ΠΏΠΈΡ‚ Π΅, Ρ‡Π΅ Π·Π° записитС ΠΎΡ‚ външния Π·Π°ΠΏΠΈΡ‚ сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ΅Π½ ΠΏΠΎΠ΄Π·Π°ΠΏΠΈΡ‚ Π½Π° прСдставСниСто [OperativeQuestions], ΠΊΠΎΠΉΡ‚ΠΎ Π·Π° [Email] = @p__linq__0 трябва Π΄Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈ ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½Π°Ρ‚Π° ΠΈΠ·Π²Π°Π΄ΠΊΠ° (Ρ‡Ρ€Π΅Π· EXISTS) Π΄ΠΎ стотици записи.

МоТС Π΄Π° ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°, Ρ‡Π΅ ΠΏΠΎΠ΄Π·Π°ΠΏΠΈΡ‚ΡŠΡ‚ трябва Π΄Π° изчисли записитС Π·Π° [Email] = @p__linq__0 само вСднъТ, Π° слСд Ρ‚ΠΎΠ²Π° Ρ‚Π΅Π·ΠΈ няколко стотици записа трябва Π΄Π° сС ΡΠ²ΡŠΡ€ΠΆΠ°Ρ‚ ΠΏΠΎ Id с Questions, ΠΈ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ Ρ‰Π΅ бъдС Π±ΡŠΡ€Π·ΠΎ.

Π’ дСйствитСлност ΠΎΠ±Π°Ρ‡Π΅ сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° послСдоватСлно ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅ Π½Π° всички Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ: Ρ‚.Π΅. ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π·Π° ΡΡŠΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΈΠ΅ Π½Π° Id Questions с Id ΠΎΡ‚ OperativeQuestions, ΠΈ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅ ΠΏΠΎ Email.

По ΡΡŠΡ‰Π΅ΡΡ‚Π²ΠΎ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚ΠΈ с дСсСтки хиляди записи Π½Π° OperativeQuestions, Π° Π²ΡΡŠΡ‰Π½ΠΎΡΡ‚ са Π½ΡƒΠΆΠ½ΠΈ само спСцифичнитС Π΄Π°Π½Π½ΠΈ ΠΏΠΎ Email.

ВСкст Π½Π° прСдставСниСто OperativeQuestions:

Π—Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ β„– 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 OperativeQuestions { get; set; }
    //...
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Query().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();

Π’ Ρ‚ΠΎΠ·ΠΈ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π΅Π½ случай сС Ρ€Π°Π·Π³Π»Π΅ΠΆΠ΄Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Ρ‚ΠΎΠ·ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π±Π΅Π· инфраструктурни ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ, Π±Π΅Π· въвСТданС Π½Π° ΠΎΡ‚Π΄Π΅Π»Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†Π° с Π³ΠΎΡ‚ΠΎΠ²ΠΈ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈ (β€žΠΠΊΡ‚ΠΈΠ²Π½ΠΈ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½ΠΈΡβ€œ), ΠΏΠΎΠ΄ която Π±ΠΈ Π±ΠΈΠ» Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ Π·Π° Π½Π΅ΠΉΠ½ΠΎΡ‚ΠΎ попълванС с Π΄Π°Π½Π½ΠΈ ΠΈ ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°Π½Π΅ Π½Π° Π°ΠΊΡ‚ΡƒΠ°Π»Π½ΠΎΡ‚ΠΎ ΠΉ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅.

Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‡Π΅ Ρ‚ΠΎΠ²Π° Π΅ Π΄ΠΎΠ±Ρ€ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, ΠΈΠΌΠ° ΠΈ Π΄Ρ€ΡƒΠ³ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π·Π° оптимизация Π½Π° Ρ‚Π°Π·ΠΈ Π·Π°Π΄Π°Ρ‡Π°.

ΠžΡΠ½ΠΎΠ²Π½Π°Ρ‚Π° Ρ†Π΅Π» Π΅ Π΄Π° сС ΠΊΠ΅ΡˆΠΈΡ€Π°Ρ‚ записитС ΠΏΠΎ [Email] = @p__linq__0 ΠΎΡ‚ ΠΈΠ·Π³Π»Π΅Π΄Π° OperativeQuestions.

Π’ΡŠΠ²Π΅ΠΆΠ΄Π°ΠΌΠ΅ Ρ‚Π°Π±Π»ΠΈΡ‡Π½Π° функция [dbo].[OperativeQuestionsUserMail] Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ.

Π˜Π·ΠΏΡ€Π°Ρ‰Π°ΠΉΠΊΠΈ Email ΠΊΠ°Ρ‚ΠΎ Π²Ρ…ΠΎΠ΄Π΅Π½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€, ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Ρ‚Π°Π±Π»ΠΈΡ†Π° с Π΄Π°Π½Π½ΠΈ:

Π—Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ β„– 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 ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»Π½ΠΈ ΠΈ Π΄Π° ΠΈΠΌΠ°Ρ‚ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»Π½ΠΈ ΠΏΠ»Π°Π½ΠΎΠ²Π΅ Π·Π° запитвания, Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠ° строга структура, Π° Π½Π΅ RETURNS TABLE AS RETURN…

Π’ Ρ‚ΠΎΠ·ΠΈ случай Ρ‚ΡŠΡ€ΡΠ΅Π½ΠΎΡ‚ΠΎ Π—Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ 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)

ΠΏΡƒΠ±Π»ΠΈΡ‡Π΅Π½ клас QuestionsDbContext : DbContext
{
    //...
    ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎ DbQuery<OperativeQuestion> ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΈΠ’ΡŠΠΏΡ€ΠΎΡΠΈ { get; set; }
    //...
    Π·Π°Ρ‰ΠΈΡ‚Π΅Π½override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Query<OperativeQuestion>().ToView("OperativeQuestions");
    }
}
 
ΠΏΡƒΠ±Π»ΠΈΡ‡Π΅Π½ статичСн клас FromSqlQueries
{
    ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎ статично IQueryable<OperativeQuestion> GetByUserEmail(this DbQuery<OperativeQuestion> source, string Email)
        => source.FromSql($"SELECT Id, Email FROM [dbo].[OperativeQuestionsUserMail] ({Email})");
}

Π˜Ρ‚ΠΎΠ³ΠΎΠ²ΠΈΡΡ‚ LINQ-запрос

var businessObjectsData = await context
    .ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΈΠ’ΡŠΠΏΡ€ΠΎΡΠΈ
    .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-800 мс Π½Π° 2-20 мс, Ρ‚.Π΅. дСсСтки ΠΏΡŠΡ‚ΠΈ ΠΏΠΎ-Π±ΡŠΡ€Π·ΠΎ.

Ако ΠΏΠΎ-усрСднСно Π²Π·Π΅ΠΌΠ΅ΠΌ, вмСсто 350 мс ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ 8 мс.

ΠžΡ‚ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΈΡ‚Π΅ плюсовС ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅:

  1. ΠΎΠ±Ρ‰ΠΎ Π½Π°ΠΌΠ°Π»Π΅Π½ΠΈΠ΅ Π½Π° Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅Ρ‚ΠΎ ΠΏΡ€ΠΈ Ρ‡Π΅Ρ‚Π΅Π½Π΅,
  2. Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ намаляванС Π½Π° вСроятността ΠΎΡ‚ блокирания
  3. Π½Π°ΠΌΠ°Π»Π΅Π½ΠΈΠ΅ Π½Π° срСдното Π²Ρ€Π΅ΠΌΠ΅ Π·Π° Π±Π»ΠΎΠΊΠΈΡ€Π°Π½Π΅ Π΄ΠΎ ΠΏΡ€ΠΈΠ΅ΠΌΠ»ΠΈΠ²ΠΈ стойности

Извод

ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡΡ‚Π° ΠΈ ΠΏΡ€Π΅Ρ†ΠΈΠ·Π½ΠΎΡ‚ΠΎ настройванС Π½Π° Π΄ΠΎΡΡ‚ΡŠΠΏΠΈΡ‚Π΅ Π΄ΠΎ Π‘Π” MS SQL Ρ‡Ρ€Π΅Π· LINQ Π΅ Π·Π°Π΄Π°Ρ‡Π°, която ΠΌΠΎΠΆΠ΅ Π΄Π° сС Ρ€Π΅ΡˆΠΈ.

Π’ Ρ‚Π°Π·ΠΈ Ρ€Π°Π±ΠΎΡ‚Π° ΠΌΠ½ΠΎΠ³ΠΎ Π²Π°ΠΆΠ½ΠΈ са Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅Ρ‚ΠΎ ΠΈ послСдоватСлността.

Π’ Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° процСса:

  1. Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΅ Π΄Π° сС провСрят Π΄Π°Π½Π½ΠΈΡ‚Π΅, с ΠΊΠΎΠΈΡ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚ΠΈ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ (стойности, ΠΈΠ·Π±Ρ€Π°Π½ΠΈ Ρ‚ΠΈΠΏΠΎΠ²Π΅ Π΄Π°Π½Π½ΠΈ)
  2. Π΄Π° сС ΠΏΡ€ΠΎΠ²Π΅Π΄Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π½Π° индСксация Π½Π° Ρ‚Π΅Π·ΠΈ Π΄Π°Π½Π½ΠΈ
  3. Π΄Π° сС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈ корСктността Π½Π° условията Π·Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈΡ‚Π΅

На слСдващата итСрация Π½Π° оптимизацията сС ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°Ρ‚:

  1. основата Π½Π° Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ ΠΈ сС опрСдСля основният Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ Π½Π° Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ
  2. повтарящи сС сходни Π±Π»ΠΎΠΊΠΎΠ²Π΅ Π½Π° Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ ΠΈ сС Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°Ρ‚ прСсСчСнитС условия
  3. Π² SSMS ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ GUI Π·Π° SQL Server ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π° сС самият SQL-Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ (ΠΈΠ·ΠΎΠ»ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΌΠ΅ΠΆΠ΄ΠΈΠ½Π½ΠΎ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ ΠΎΡ‚ Π΄Π°Π½Π½ΠΈ, построяванС Π½Π° Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚Π½ΠΎ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ с ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Ρ‚ΠΎΠ²Π° Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ (ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠΌΠ° няколко))
  4. Π½Π° послСдния Π΅Ρ‚Π°ΠΏ, Π²Π·Π΅ΠΌΠ°ΠΉΠΊΠΈ Π·Π° основа рСзултатния SQL-Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅, сС прСустроява структурата Π½Π° LINQ-Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ

Π’ ΠΊΡ€Π°ΠΉΠ½Π° смСтка ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎΡ‚ΠΎ LINQ-Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ трябва Π΄Π° станС ΠΏΠΎ структура ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½ΠΎ Π½Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°Π½ΠΎΡ‚ΠΎ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»Π½ΠΎ SQL-Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ ΠΎΡ‚ Ρ‚ΠΎΡ‡ΠΊΠ° 3.

Благодарности

ΠžΠ³Ρ€ΠΎΠΌΠ½ΠΎ благодаря Π½Π° ΠΊΠΎΠ»Π΅Π³ΠΈΡ‚Π΅ jobgemws ΠΈ alex_ozr ΠΎΡ‚ компанията Fortis Π·Π° ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° ΠΏΡ€ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ°Ρ‚Π° Π½Π° Ρ‚ΠΎΠ·ΠΈ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π».

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster