C#.NET හි LINQ විමසුම් ප්‍රශස්ත කිරීම සඳහා ක්‍රම

හැඳින්වීම

В මේ ලිපිය කියවන්න සමහර ප්‍රශස්තිකරණ ක්‍රම සලකා බලන ලදී LINQ විමසුම්.
මෙන්න අපි සම්බන්ධ කේත ප්‍රශස්තිකරණය සඳහා තවත් ප්‍රවේශයන් කිහිපයක් ඉදිරිපත් කරමු LINQ විමසුම්.

එය දන්නා කරුණකි ලින්ක්(භාෂා-ඒකාබද්ධ විමසුම) යනු දත්ත මූලාශ්‍රයක් විමසීම සඳහා සරල සහ පහසු භාෂාවකි.

А LINQ සිට SQL දක්වා DBMS එකක දත්ත ප්‍රවේශ කිරීමේ තාක්ෂණයකි. මෙය දත්ත සමඟ වැඩ කිරීම සඳහා ප්‍රබල මෙවලමක් වන අතර, ප්‍රකාශන භාෂාවක් හරහා විමසුම් ගොඩනගනු ලබන අතර, එය පසුව බවට පරිවර්තනය වේ. SQL විමසුම් වේදිකාව සහ ක්රියාත්මක කිරීම සඳහා දත්ත සමුදා සේවාදායකය වෙත යවනු ලැබේ. අපගේ නඩුවේදී, DBMS යන්නෙන් අප අදහස් කරන්නේ MS SQL සේවාදායකය.

කෙසේ වෙතත්, LINQ විමසුම් ප්‍රශස්ත ලෙස ලියා ඇති ඒවා බවට පරිවර්තනය නොවේ SQL විමසුම්, පළපුරුදු DBA කෙනෙකුට ප්‍රශස්තකරණයේ සියලු සූක්ෂ්මතා සමඟ ලිවිය හැකිය SQL විමසුම්:

  1. ප්රශස්ත සම්බන්ධතා (JOIN) සහ ප්රතිඵල පෙරීම (WHERE)
  2. සම්බන්ධතා සහ කණ්ඩායම් කොන්දේසි භාවිතා කිරීමේදී බොහෝ සූක්ෂ්මතා
  3. කොන්දේසි වෙනුවට බොහෝ වෙනස්කම් IN මත විදහා දක්වයිи ඇතුළත නොවේ, <> මත විදහා දක්වයි
  4. තාවකාලික වගු, CTE, වගු විචල්‍ය හරහා ප්‍රතිඵල අතරමැදි හැඹිලිගත කිරීම
  5. වාක්‍ය භාවිතය (විකල්පය) උපදෙස් සහ වගු ඉඟි සමඟ සමග (...)
  6. තේරීම් වලදී අතිරික්ත දත්ත කියවීම් ඉවත් කිරීමට එක් මාධ්‍යයක් ලෙස සුචිගත දසුන් භාවිතා කිරීම

ප්රතිඵලය ප්රධාන කාර්ය සාධන බාධක SQL විමසුම් සම්පාදනය කරන විට LINQ විමසුම් ඒවා නම්:

  1. එක් ඉල්ලීමක් තුළ සම්පූර්ණ දත්ත තේරීමේ යාන්ත්‍රණය ඒකාබද්ධ කිරීම
  2. සමාන කේත කොටස් අනුපිටපත් කිරීම, අවසානයේ බහු අනවශ්‍ය දත්ත කියවීම් වලට තුඩු දෙයි
  3. බහු සංරචක කොන්දේසි කණ්ඩායම් (තාර්කික "සහ" සහ "හෝ") - සහ и OR, සංකීර්ණ තත්ත්‍වයට ඒකාබද්ධ වීම, අවශ්‍ය ක්ෂේත්‍ර සඳහා සුදුසු පොකුරු නොවන දර්ශක ඇති ප්‍රශස්තකාරකය අවසානයේ පොකුරු දර්ශකයට එරෙහිව පරිලෝකනය කිරීමට පටන් ගනී (දර්ශක ස්කෑන්) කොන්දේසි කණ්ඩායම් විසින්
  4. උප විමසුම්වල ගැඹුරු කැදැල්ල විග්‍රහ කිරීම ඉතා ගැටළු සහගත කරයි SQL ප්රකාශයන් සහ සංවර්ධකයින්ගේ පැත්තෙන් විමසුම් සැලැස්ම විශ්ලේෂණය කිරීම සහ DBA

ප්‍රශස්තිකරණ ක්‍රම

දැන් අපි කෙලින්ම ප්‍රශස්තිකරණ ක්‍රම වෙත යමු.

1) අතිරේක සුචිගත කිරීම

බොහෝ විට සම්පූර්ණ විමසුම ප්‍රධාන වගු එකක් හෝ දෙකක් වටා (යෙදුම්-පුද්ගල-මෙහෙයුම්) සහ සම්මත කොන්දේසි මාලාවක් (isClosed, Cancelled, 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) එක් නව ගුණාංගයකට ගුණාංග ඒකාබද්ධ කිරීම

සමහර විට කොන්දේසි සමූහයක් සඳහා පදනමක් ලෙස සේවය කරන එක් වගුවකින් සමහර ක්ෂේත්‍ර එක් නව ක්ෂේත්‍රයක් හඳුන්වා දීමෙන් ප්‍රතිස්ථාපනය කළ හැකිය.

සාමාන්‍යයෙන් බිටු හෝ පූර්ණ සංඛ්‍යා සහිත තත්ව ක්ෂේත්‍ර සඳහා මෙය විශේෂයෙන්ම සත්‍ය වේ.

උදාහරණ:

වසා ඇත = 0 සහ අවලංගු = 0 සහ සක්රිය = 0 ආදේශ කර ඇත තත්ත්වය = 1.

මෙම තත්ව වගුවේ පුරවා ඇති බව සහතික කිරීම සඳහා පූර්ණ සංඛ්‍යා තත්ව ගුණාංගය හඳුන්වා දෙනු ලබන්නේ මෙහිදීය. ඊළඟට, මෙම නව ගුණාංගය සුචිගත කර ඇත.

මෙය කාර්ය සාධන ගැටලුවට මූලික විසඳුමකි, මන්ද අපි අනවශ්‍ය ගණනය කිරීම් වලින් තොරව දත්ත වෙත ප්‍රවේශ වන්නෙමු.

3) දර්ශනයේ ද්රව්යකරණය

අවාසනාවකට, තුළ LINQ විමසුම් තාවකාලික වගු, CTE සහ වගු විචල්‍ය කෙලින්ම භාවිතා කළ නොහැක.

කෙසේ වෙතත්, මෙම නඩුව සඳහා ප්රශස්ත කිරීම සඳහා තවත් ක්රමයක් තිබේ - සුචිගත දර්ශන.

තත්ව කණ්ඩායම (ඉහත උදාහරණයෙන්) වසා ඇත = 0 සහ අවලංගු = 0 සහ සක්රිය = 0 (හෝ වෙනත් සමාන කොන්දේසි සමූහයක්) ඒවා සුචිගත දසුනක භාවිතා කිරීමට හොඳ විකල්පයක් බවට පත් වේ, විශාල කට්ටලයකින් කුඩා දත්ත පෙත්තක් හැඹිලිගත කරයි.

නමුත් දර්ශනයක් සාක්ෂාත් කර ගැනීමේදී සීමාවන් ගණනාවක් තිබේ:

  1. උප ප්‍රශ්න, වගන්ති භාවිතය විදහා දක්වයි භාවිතයෙන් ප්රතිස්ථාපනය කළ යුතුය JOIN
  2. ඔබට වාක්‍ය භාවිතා කළ නොහැක යුනියන්, සියලු එකමුතුව, බැහැර කිරීම, අන්තර්
  3. ඔබට වගු ඉඟි සහ වගන්ති භාවිතා කළ නොහැක විකල්පය
  4. චක්‍ර සමඟ වැඩ කිරීමට හැකියාවක් නැත
  5. විවිධ වගු වලින් එක දසුනකින් දත්ත ප්‍රදර්ශනය කළ නොහැක

සුචිගත දසුනක් භාවිතා කිරීමේ සැබෑ ප්‍රතිලාභය ලබා ගත හැක්කේ එය සැබවින්ම සුචිගත කිරීමෙන් පමණක් බව මතක තබා ගැනීම වැදගත්ය.

නමුත් දර්ශනයක් ඇමතීමේ දී, මෙම දර්ශක භාවිතා නොකළ හැකි අතර, ඒවා පැහැදිලිව භාවිතා කිරීමට, ඔබ විසින් නියම කළ යුතුය (NOEXPAND) සමඟ.

සිට LINQ විමසුම් වගු ඉඟි නිර්වචනය කළ නොහැක, එබැවින් ඔබට වෙනත් නිරූපණයක් සෑදිය යුතුය - පහත දැක්වෙන පෝරමයේ "එතන්න":

CREATE VIEW ИМЯ_представления AS SELECT * FROM MAT_VIEW WITH (NOEXPAND);

4) වගු කාර්යයන් භාවිතා කිරීම

බොහෝ විට ඇතුලේ LINQ විමසුම් සංකීර්ණ ව්‍යුහයක් සහිත දර්ශන භාවිතා කරන උප විමසුම්වල විශාල කොටස් හෝ බ්ලොක් ඉතා සංකීර්ණ සහ උපප්‍රශස්ත ක්‍රියාත්මක කිරීමේ ව්‍යුහයක් සහිත අවසාන විමසුමක් සාදයි.

වගු කාර්යයන් භාවිතා කිරීමේ ප්‍රධාන ප්‍රතිලාභ LINQ විමසුම්:

  1. දර්ශන වලදී මෙන්, වස්තුවක් ලෙස භාවිතා කිරීමට සහ නියම කිරීමට ඇති හැකියාව, නමුත් ඔබට ආදාන පරාමිති සමූහයක් සම්මත කළ හැකිය:
    කාර්යයෙන් (@param1, @param2 ...)
    එහි ප්රතිඵලයක් වශයෙන්, නම්යශීලී දත්ත නියැදීමක් ලබා ගත හැකිය
  2. වගු ශ්‍රිතයක් භාවිතා කිරීමේදී, ඉහත විස්තර කර ඇති සුචිගත දර්ශන සම්බන්ධයෙන් එවැනි ප්‍රබල සීමාවන් නොමැත:
    1. වගු ඉඟි:
      හරහා ලින්ක් කුමන දර්ශක භාවිතා කළ යුතුද යන්න සහ විමසන විට දත්ත හුදකලා මට්ටම තීරණය කිරීමට ඔබට නියම කළ නොහැක.
      නමුත් කාර්යයට මෙම හැකියාවන් ඇත.
      ශ්‍රිතය සමඟින්, ඔබට දර්ශක සමඟ වැඩ කිරීමේ නීති රීති සහ දත්ත හුදකලා මට්ටම් අර්ථ දක්වා ඇති තරමක් ස්ථාවර ක්‍රියාත්මක කිරීමේ විමසුම් සැලැස්මක් ලබා ගත හැකිය.
    2. ශ්‍රිතය භාවිතා කිරීමෙන්, සුචිගත දර්ශන හා සසඳන විට, ලබා ගැනීමට ඉඩ ලබා දේ:
      • සංකීර්ණ දත්ත නියැදි තර්කනය (ලූප භාවිතයෙන් පවා)
      • විවිධ වගු වලින් දත්ත ලබා ගැනීම
      • භාවිතය යුනියන් и විදහා දක්වයි

  3. පිරිනැමීම විකල්පය අපට සමගාමී පාලනය සැපයීමට අවශ්‍ය වූ විට ඉතා ප්‍රයෝජනවත් වේ විකල්පය (MAXDOP N), විමසුම් ක්රියාත්මක කිරීමේ සැලැස්මේ අනුපිළිවෙල. උදාහරණ වශයෙන්:
    • ඔබට විමසුම් සැලැස්ම බලහත්කාරයෙන් ප්‍රතිනිර්මාණය කිරීමක් නියම කළ හැක විකල්පය (නැවත සම්පාදනය)
    • විමසුමේ දක්වා ඇති සම්බන්ධ වීමේ අනුපිළිවෙල භාවිතා කිරීමට විමසුම් සැලැස්මට බල කළ යුතුද යන්න ඔබට සඳහන් කළ හැක විකල්පය (FORCE Order)

    ගැන වැඩි විස්තර විකල්පය විස්තර කර ඇත මෙහි.

  4. පටුම සහ වඩාත්ම අවශ්‍ය දත්ත පෙත්ත භාවිතා කරමින්:
    විශාල දත්ත කට්ටල හැඹිලිවල ගබඩා කිරීම අවශ්‍ය නොවේ (සුචිගත දර්ශන වල මෙන්), ඔබට තවමත් පරාමිතිය අනුව දත්ත පෙරීමට අවශ්‍ය වේ.
    උදාහරණයක් ලෙස, පෙරහන සහිත වගුවක් තිබේ WHERE ක්ෂේත්ර තුනක් භාවිතා වේ (a, b, c).

    සාම්ප්‍රදායිකව, සියලුම ඉල්ලීම් වලට නියත කොන්දේසියක් ඇත a = 0 සහ b = 0.

    කෙසේ වෙතත්, ක්ෂේත්රය සඳහා ඉල්ලීම c වඩා විචල්ය.

    කොන්දේසියට ඉඩ දෙන්න a = 0 සහ b = 0 අවශ්‍ය ප්‍රතිඵල මාලාව වාර්තා දහස් ගණනකට සීමා කිරීමට එය සැබවින්ම අපට උපකාර කරයි, නමුත් කොන්දේසිය ක්‍රියාත්මකයි с තේරීම වාර්තා සියයකට සීමා කරයි.

    මෙහි වගුවේ කාර්යය වඩා හොඳ විකල්පයක් විය හැකිය.

    එසේම, වගු ශ්‍රිතයක් ක්‍රියාත්මක කිරීමේ කාලය තුළ වඩාත් පුරෝකථනය කළ හැකි සහ ස්ථාවර වේ.

උදාහරණ

උදාහරණයක් ලෙස ප්‍රශ්න දත්ත සමුදාය භාවිතා කරමින් උදාහරණ ක්‍රියාත්මක කිරීමක් බලමු.

ඉල්ලීමක් තියෙනවා තෝරන්න, වගු කිහිපයක් ඒකාබද්ධ කර එක් දසුනක් භාවිතා කරයි (ක්‍රියාකාරී ප්‍රශ්න), එහි අනුබද්ධය විද්‍යුත් තැපෑලෙන් (මාර්ගය හරහා) විදහා දක්වයි) "ක්‍රියාකාරී ප්‍රශ්න" වෙත:

ඉල්ලීම අංක 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] දර්ශනය මත ක්‍රියාත්මක වන අතර, එය [ඊමේල්] = @p__linq__0 සඳහා ප්‍රතිදාන තේරීම සීමා කිරීමට අපට ඉඩ දිය යුතුය ( හරහා විදහා දක්වයි) වාර්තා සිය ගණනක් දක්වා.

තවද උප විමසුම [ඊමේල්] = @p__linq__0 මගින් වාර්තා ගණනය කළ යුතු බව පෙනේ, ඉන්පසු මෙම වාර්තා සිය ගණන ප්‍රශ්න සමඟ Id මගින් සම්බන්ධ කළ යුතු අතර, විමසුම වේගවත් වනු ඇත.

ඇත්ත වශයෙන්ම, සියලුම වගු වල අනුක්‍රමික සම්බන්ධතාවයක් ඇත: මෙහෙයුම් ප්‍රශ්න වලින් Id සමඟ Id ප්‍රශ්නවල ලිපි හුවමාරුව පරීක්ෂා කිරීම සහ විද්‍යුත් තැපෑලෙන් පෙරීම.

ඇත්ත වශයෙන්ම, ඉල්ලීම සියලුම මෙහෙයුම් ප්‍රශ්න වාර්තා දස දහස් ගණනක් සමඟ ක්‍රියා කරයි, නමුත් අවශ්‍ය වන්නේ විද්‍යුත් තැපෑල හරහා උනන්දුවක් දක්වන දත්ත පමණි.

මෙහෙයුම් ප්‍රශ්න පෙළ බලන්න:

ඉල්ලීම අංක 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();

මෙම විශේෂිත අවස්ථාවෙහිදී, යටිතල ව්‍යුහාත්මක වෙනස්කම් නොමැතිව, දත්ත පිරවීමට සහ යාවත්කාලීනව තබා ගැනීමට යාන්ත්‍රණයක් අවශ්‍ය වන, සූදානම් කළ ප්‍රතිඵල (“ක්‍රියාකාරී විමසුම්”) සහිත වෙනම වගුවක් හඳුන්වා නොදී, අපි මෙම ගැටලුවට විසඳුමක් සලකා බලමු. .

මෙය හොඳ විසඳුමක් වුවද, මෙම ගැටළුව ප්රශස්ත කිරීම සඳහා තවත් විකල්පයක් ඇත.

ප්‍රධාන අරමුණ වන්නේ [ඊමේල්] = @p__linq__0 මගින් OperativeQuestions දසුනෙන් ඇතුළත් කිරීම් හැඹිලිගත කිරීමයි.

වගු ශ්‍රිතය [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 වෙත විමසීම් ප්‍රශස්ත වීමට සහ ප්‍රශස්ත විමසුම් සැලසුම් තිබීම සඳහා, දැඩි ව්‍යුහයක් අවශ්‍ය වන අතර එසේ නොවේ. ආපසු හැරවුම් වගුව ආපසු හැරවීම...

මෙම අවස්ථාවේදී, අවශ්‍ය Query 1 Query 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-800 ms සිට 2-20 ms දක්වා පහත වැටී ඇත, එනම් දස ගුණයකින් වේගවත් වේ.

අපි එය වඩා සාමාන්‍ය ලෙස ගත්තොත්, 350 ms වෙනුවට අපට ms 8 ක් ලැබුණි.

පැහැදිලි වාසි වලින් අපට ලැබෙන්නේ:

  1. කියවීමේ බරෙහි සාමාන්‍ය අඩුවීම,
  2. අවහිර වීමේ සම්භාවිතාව සැලකිය යුතු ලෙස අඩු කිරීම
  3. සාමාන්ය අවහිර කිරීමේ කාලය පිළිගත හැකි අගයන් දක්වා අඩු කිරීම

නිගමනය

දත්ත සමුදා ඇමතුම් ප්‍රශස්තකරණය සහ මනාව සකස් කිරීම MS SQL හරහා ලින්ක් යන්න විසඳිය හැකි ගැටලුවකි.

මෙම කාර්යයේදී අවධානය සහ ස්ථාවරත්වය ඉතා වැදගත් වේ.

ක්රියාවලිය ආරම්භයේ දී:

  1. ඉල්ලීම ක්‍රියාත්මක වන දත්ත පරීක්ෂා කිරීම අවශ්‍ය වේ (අගය, තෝරාගත් දත්ත වර්ග)
  2. මෙම දත්ත නිසි ලෙස සුචිගත කිරීම සිදු කරන්න
  3. වගු අතර කොන්දේසි සම්බන්ධ කිරීමේ නිවැරදි බව පරීක්ෂා කරන්න

ඊළඟ ප්‍රශස්තිකරණ පුනරාවර්තනය හෙළි කරයි:

  1. ඉල්ලීමේ පදනම සහ ප්‍රධාන ඉල්ලීම් පෙරහන නිර්වචනය කරයි
  2. සමාන විමසුම් වාරණ නැවත නැවත කිරීම සහ කොන්දේසිවල ඡේදනය විශ්ලේෂණය කිරීම
  3. SSMS හෝ වෙනත් GUI සඳහා SQL සේවාදායකය තමා ප්‍රශස්ත කරයි SQL විමසුම (අතරමැදි දත්ත ගබඩාවක් වෙන් කිරීම, මෙම ගබඩාව භාවිතයෙන් ලැබෙන විමසුම ගොඩ නැගීම (කිහිපයක් තිබිය හැක))
  4. අවසාන අදියරේදී, ප්රතිඵලය පදනමක් ලෙස ගනිමින් SQL විමසුම, ව්යුහය නැවත ගොඩනඟමින් පවතී LINQ විමසුම

ප්රතිඵලය LINQ විමසුම හඳුනාගත් ප්‍රශස්ත ව්‍යුහයට සමාන විය යුතුය SQL විමසුම 3 වන ස්ථානයේ සිට.

පිළිගැනීම්

සගයන්ට බොහෝම ස්තූතියි jobgemws и alex_ozr සමාගමෙන් ෆෝටිස් මෙම ද්රව්ය සකස් කිරීම සඳහා සහාය සඳහා.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න