C#.NET ۾ LINQ سوالن کي بهتر ڪرڻ جا طريقا

تعارف

В اهو مضمون ڪجهه اصلاح جا طريقا سمجهيا ويا LINQ سوال.
هتي اسان ڪجهه وڌيڪ طريقا پيش ڪندا آهيون ڪوڊ جي اصلاح سان لاڳاپيل LINQ سوال.

اهو معلوم آهي ته لنڪ(Language-Integrated Query) ڊيٽا ماخذ جي سوال ڪرڻ لاءِ هڪ سادي ۽ آسان ٻولي آهي.

А LINQ کان SQL ڊي بي ايم ايس ۾ ڊيٽا تائين رسائي جي ٽيڪنالاجي آهي. هي ڊيٽا سان ڪم ڪرڻ لاءِ هڪ طاقتور اوزار آهي، جتي سوالن کي هڪ بياني ٻولي ذريعي ٺاهيو ويندو آهي، جنهن کي پوءِ ان ۾ تبديل ڪيو ويندو. SQL سوال پليٽ فارم ۽ عمل لاء ڊيٽابيس سرور ڏانهن موڪليو ويو. اسان جي صورت ۾، ڊي بي ايم ايس پاران اسان جو مطلب آهي MS SQL سرور.

جڏهن ته، LINQ سوال بهتر طور تي لکندڙن ۾ تبديل نه ڪيا ويا آهن SQL سوال، جنهن کي هڪ تجربيڪار DBA اصلاح جي سڀني نونسن سان لکي سگهي ٿو SQL سوال:

  1. بهترين ڪنيڪشن (JOIN) ۽ نتيجن کي فلٽر ڪرڻ (جڏهن)
  2. ڪنيڪشن ۽ گروپ جي حالتن کي استعمال ڪرڻ ۾ ڪيترائي nuances
  3. حالتن جي بدلي ۾ ڪيترائي تغيرات IN تي وجودَи اندر نه، <> تي وجودَ
  4. عارضي جدولن، CTE، ٽيبل متغير ذريعي نتيجن جي وچولي ڪيشنگ
  5. جملي جو استعمال (OPTION) هدايتون ۽ ٽيبل اشارن سان سان (...)
  6. چونڊ دوران بيڪار ڊيٽا پڙهڻ کان نجات حاصل ڪرڻ جو هڪ وسيلو طور تي ترتيب ڏنل نظارن کي استعمال ڪندي

نتيجن جي مکيه ڪارڪردگي جي رڪاوٽون SQL سوال جڏهن گڏ ڪرڻ LINQ سوال آهن:

  1. ھڪڙي درخواست ۾ پوري ڊيٽا جي چونڊ ميڪانيزم کي گڏ ڪرڻ
  2. ڪوڊ جي هڪجهڙائي واري بلاڪ کي نقل ڪرڻ، جيڪو آخرڪار ڪيترن ئي غير ضروري ڊيٽا پڙهڻ جي ڪري ٿو
  3. گهڻن حصن جي حالتن جا گروپ (منطقي "۽" ۽ "يا") - ۽ и OR، پيچيده حالتن ۾ ملائيندي، حقيقت ڏانهن وٺي وڃي ٿو ته اصلاحي، ضروري شعبن لاءِ مناسب غير ڪلسٽرڊ انڊيڪس هجڻ ڪري، آخرڪار ڪلستر ٿيل انڊيڪس جي خلاف اسڪين ڪرڻ شروع ڪري ٿو (انڊيڪس اسڪين) شرطن جي گروپن طرفان
  4. ذيلي سوالن جو deep nesting پارس ڪرڻ کي تمام ڏکيو بڻائي ٿو SQL بيان ۽ ڊولپرز جي حصي تي سوال جي منصوبي جو تجزيو ۽ DBA

اصلاحي طريقا

هاڻي اچو ته سڌو سنئون اصلاح جي طريقن ڏانهن وڃو.

1) اضافي انڊيڪسنگ

اهو بهترين آهي فلٽرن تي غور ڪرڻ لاءِ مکيه چونڊ جدولن تي، ڇاڪاڻ ته اڪثر ڪري سڄو سوال هڪ يا ٻه مکيه جدولن (ايپليڪيشن-ماڻهن-آپريشنز) جي چوڌاري ٺهيل هوندو آهي ۽ شرطن جي معياري سيٽ سان (IsClosed، منسوخ ٿيل، فعال، اسٽيٽس). اهو ضروري آهي ته سڃاڻپ نموني لاء مناسب انڊيڪس ٺاهي.

هي حل سمجھ ۾ اچي ٿو جڏهن انهن شعبن کي چونڊيو خاص طور تي سوال ڏانهن موٽايل سيٽ کي محدود ڪري ٿو.

مثال طور، اسان وٽ 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 سوال عارضي جدول، CTEs، ۽ ٽيبل متغير سڌو سنئون استعمال نٿا ڪري سگھجن.

تنهن هوندي، هن معاملي لاء بهتر ڪرڻ جو هڪ ٻيو طريقو آهي - ترتيب ڏنل نظريا.

حالت گروپ (مٿي ڏنل مثال کان) بند ٿيل = 0 ۽ منسوخ = 0 ۽ فعال = 0 (يا ٻين ساڳين حالتن جو هڪ سيٽ) انهن کي استعمال ڪرڻ لاءِ هڪ سٺو آپشن بڻجي ويندو آهي انڊيڪس ٿيل ڏيک ۾، وڏي سيٽ مان ڊيٽا جي هڪ ننڍڙي سلائس کي ڪيش ڪندي.

پر اتي ڪجھ پابنديون آھن جڏھن ھڪڙي نظر کي مادي ڪرڻ:

  1. ذيلي سوالن جو استعمال، شقون وجودَ استعمال ڪندي تبديل ڪيو وڃي JOIN
  2. توهان جملا استعمال نٿا ڪري سگهو يونين, يونين سڀ, EXCEPTION, چوندو
  3. توھان ٽيبل اشارا ۽ شقون استعمال نٿا ڪري سگھو OPTION
  4. سائيڪل سان ڪم ڪرڻ جو ڪو به امڪان ناهي
  5. مختلف جدولن مان هڪ ڏيک ۾ ڊيٽا کي ظاهر ڪرڻ ناممڪن آهي

اهو ياد رکڻ ضروري آهي ته انڊيڪس ٿيل ڏيک استعمال ڪرڻ جو حقيقي فائدو صرف ان کي اصل ۾ ترتيب ڏيڻ سان حاصل ڪري سگهجي ٿو.

پر جڏهن ڪنهن ڏيک کي سڏين ٿا، اهي انڊيڪس استعمال نٿا ڪري سگهجن، ۽ انهن کي واضح طور تي استعمال ڪرڻ لاءِ، توهان کي وضاحت ڪرڻ گهرجي سان (NOEXPAND).

کان وٺي LINQ سوال ٽيبل جي اشارن جي وضاحت ڪرڻ ناممڪن آهي، تنهنڪري توهان کي هڪ ٻيو نمائندگي ٺاهڻو پوندو - هيٺ ڏنل فارم جو "لپڻ":

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

4) ٽيبل افعال استعمال ڪندي

اڪثر ۾ LINQ سوال ذيلي سوالن جا وڏا بلاڪ يا بلاڪ هڪ پيچيده ڍانچي سان نظرين کي استعمال ڪندي هڪ انتهائي پيچيده ۽ ذيلي اختياري عمل جي جوڙجڪ سان حتمي سوال ٺاهيندا آهن.

۾ ٽيبل فنڪشن استعمال ڪرڻ جا اهم فائدا LINQ سوال:

  1. قابليت، جيئن ته نظرن جي صورت ۾، استعمال ڪيو وڃي ۽ هڪ اعتراض جي طور تي بيان ڪيو وڃي، پر توهان ان پٽ پيٽرولر جو هڪ سيٽ پاس ڪري سگهو ٿا:
    فنڪشن کان (@param1، @param2 ...)
    نتيجي طور، لچڪدار ڊيٽا نموني حاصل ڪري سگھجي ٿو
  2. ٽيبل جي فنڪشن کي استعمال ڪرڻ جي صورت ۾، مٿي بيان ڪيل انڊيڪس ٿيل نظرين جي صورت ۾ اهڙيون مضبوط پابنديون نه آهن:
    1. ٽيبل اشارو:
      через لنڪ توھان وضاحت نٿا ڪري سگھو ته ڪھڙا انڊيڪس استعمال ڪيا وڃن ۽ پڇا ڳاڇا ڪرڻ وقت ڊيٽا جي اڪيلائي جي سطح کي طئي ڪيو وڃي.
      پر فنڪشن ۾ اهي صلاحيتون آهن.
      فنڪشن سان، توهان حاصل ڪري سگهو ٿا هڪ مسلسل مسلسل عملدرآمد سوال جو منصوبو، جتي انڊيڪس ۽ ڊيٽا جي الڳ ڪرڻ جي سطحن سان ڪم ڪرڻ جا قاعدا بيان ڪيا ويا آهن.
    2. فنڪشن کي استعمال ڪرڻ جي اجازت ڏئي ٿو، ترتيب ڏنل نظرن جي مقابلي ۾، حاصل ڪرڻ لاء:
      • پيچيده ڊيٽا نموني منطق (جيتوڻيڪ لوپ استعمال ڪندي)
      • ڪيترن ئي مختلف جدولن مان ڊيٽا حاصل ڪرڻ
      • جي استعمال يونين и وجودَ

  3. پيش OPTION تمام مفيد جڏهن اسان کي هڪجهڙائي ڪنٽرول مهيا ڪرڻ جي ضرورت آهي اختيار (MAXDOP N)، سوال جي عمل جي منصوبي جو حڪم. مثال طور:
    • توھان وضاحت ڪري سگھو ٿا زبردستي ٻيهر ٺاھڻ جو سوال پلان اختيار (ٻيهر ڪمپيل)
    • توھان وضاحت ڪري سگھوٿا ته سوال ۾ بيان ڪيل شامل آرڊر استعمال ڪرڻ لاءِ سوال جي منصوبي کي مجبور ڪيو وڃي اختيار (فورس آرڊر)

    بابت وڌيڪ تفصيل OPTION بيان ڪيل هتي.

  4. تمام تنگ ۽ سڀ کان وڌيڪ گهربل ڊيٽا سلائس استعمال ڪندي:
    ڪيش ۾ وڏي ڊيٽا سيٽ کي ذخيرو ڪرڻ جي ڪا ضرورت ناهي (جيئن ته انڊيڪس ٿيل نظارن جي صورت ۾ آهي)، جنهن مان توهان اڃا تائين ڊيٽا کي پيٽرولر ذريعي فلٽر ڪرڻ جي ضرورت آهي.
    مثال طور، ھڪڙو ٽيبل آھي جنھن جو فلٽر جڏهن ٽي شعبا استعمال ڪيا ويا آهن (a, b, c).

    روايتي طور تي، سڀني درخواستن کي مستقل حالت آهي a = 0 ۽ ب = 0.

    بهرحال، فيلڊ جي درخواست c وڌيڪ متغير.

    ڏيو شرط a = 0 ۽ ب = 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])
));

نظارو هڪ پيچيده جوڙجڪ آهي: ان ۾ ذيلي پڇا ڳاڇا شامل آهن ۽ ترتيب ڏيڻ کي استعمال ڪري ٿو ڊسٽينڪ، جيڪو عام طور تي هڪ انتهائي وسيلن وارو آپريشن آهي.

OperativeQuestions مان هڪ نمونو اٽڪل ڏهه هزار رڪارڊ آهي.

هن سوال سان گڏ بنيادي مسئلو اهو آهي ته ٻاهرين سوالن جي رڪارڊ لاء، هڪ اندروني ذيلي سوال [OperativeQuestions] ڏيک تي عمل ڪيو ويندو آهي، جيڪو [اي ميل] = @p__linq__0 لاء اسان کي اجازت ڏئي ٿو ته اسان کي ٻاھرين چونڊ کي محدود ڪرڻ جي اجازت ڏيو (ذريعي وجودَ) سوين رڪارڊ تائين.

۽ اهو لڳي سگھي ٿو ته ذيلي پڇاڙيءَ کي [اي ميل] = @p__linq__0 ذريعي هڪ ڀيرو رڪارڊ جو حساب ڏيڻ گهرجي، ۽ پوءِ اهي ٻه سئو رڪارڊ سوالن سان Id سان ڳنڍڻ گهرجن، ۽ سوال تيز ٿي ويندا.

حقيقت ۾، سڀني جدولن جو هڪ ترتيب وار ڪنيڪشن آهي: OperativeQuestions کان 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 (اي ايف ڪور 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 لاءِ سوالن لاءِ بھترين ۽ بھترين سوالن جا منصوبا آھن، ھڪ سخت ڍانچي جي ضرورت آھي، ۽ نه واپسي جي طور تي واپسي ٽيبل...

انهي صورت ۾، گهربل سوال 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-800 ms کان گهٽجي ويو آهي، 2-20 ms وغيره، يعني ڏهه ڀيرا تيز.

جيڪڏهن اسان ان کي وڌيڪ سراسري طور وٺي، پوء 350 ms جي بدران اسان کي 8 ms ملي.

واضح فائدن مان اسان پڻ حاصل ڪريون ٿا:

  1. پڙهڻ جي لوڊ ۾ عام گهٽتائي،
  2. بلاڪ جي امڪان ۾ اهم گهٽتائي
  3. قابل قبول قدرن تائين اوسط بلاڪنگ وقت کي گھٽائڻ

ٿڪل

ڊيٽابيس ڪالن جي اصلاح ۽ فائن ٽيوننگ MS SQL через لنڪ هڪ مسئلو آهي جيڪو حل ڪري سگهجي ٿو.

هن ڪم ۾ توجه ۽ مستقل مزاجي تمام ضروري آهي.

عمل جي شروعات ۾:

  1. اهو ضروري آهي ته ڊيٽا کي جانچيو وڃي جنهن سان درخواست ڪم ڪري ٿي (قدر، چونڊيل ڊيٽا جا قسم)
  2. هن ڊيٽا جي مناسب ترتيب ڏيڻ
  3. جدولن جي وچ ۾ شامل ٿيڻ جي حالتن جي درستگي کي چيڪ ڪريو

ايندڙ اصلاح جي تکرار ظاهر ڪري ٿي:

  1. درخواست جي بنياد تي ۽ بنيادي درخواست فلٽر کي بيان ڪري ٿو
  2. ساڳيو سوال بلاڪ کي ورجائڻ ۽ حالتن جي چونڪ جو تجزيو ڪرڻ
  3. SSMS يا ٻي GUI ۾ SQL سرور پاڻ کي بهتر بڻائي ٿو SQL سوال (هڪ وچولي ڊيٽا اسٽوريج کي مختص ڪرڻ، هن اسٽوريج کي استعمال ڪندي نتيجن جي سوال کي تعمير ڪرڻ (ڪيترائي ٿي سگهي ٿي))
  4. آخري مرحلي ۾، نتيجي جي بنياد تي وٺي SQL سوال، ڍانچي کي ٻيهر تعمير ڪيو پيو وڃي LINQ سوال

نتيجو LINQ سوال ڍانچي ۾ هڪجهڙائي هجڻ گهرجي سڃاڻپ بهتر SQL سوال پوائنٽ 3 کان.

مڃيل نشانيون

ساٿين جي وڏي مهرباني نوڪريون и alex_ozr ڪمپني کان قلعي جو هن مواد جي تياري ۾ مدد لاء.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو