C#.NET میں LINQ سوالات کو بہتر بنانے کے طریقے

تعارف

В یہ مضمون کچھ اصلاحی طریقوں پر غور کیا گیا۔ LINQ کے سوالات.
یہاں ہم کوڈ کی اصلاح سے متعلق کچھ اور نقطہ نظر پیش کرتے ہیں۔ LINQ کے سوالات.

یہ معلوم ہے کہ لنک(Language-Integrated Query) ڈیٹا سورس سے استفسار کرنے کے لیے ایک سادہ اور آسان زبان ہے۔

А LINQ سے SQL ڈی بی ایم ایس میں ڈیٹا تک رسائی کے لیے ایک ٹیکنالوجی ہے۔ ڈیٹا کے ساتھ کام کرنے کے لیے یہ ایک طاقتور ٹول ہے، جہاں استفسارات کو اعلانیہ زبان کے ذریعے بنایا جاتا ہے، جسے بعد میں ایس کیو ایل کے سوالات پلیٹ فارم اور عمل درآمد کے لیے ڈیٹا بیس سرور کو بھیجا گیا۔ ہمارے معاملے میں، ڈی بی ایم ایس سے ہمارا مطلب ہے۔ ایم ایس ایس کیو ایل سرور.

تاہم، LINQ کے سوالات بہترین تحریروں میں تبدیل نہیں ہوتے ہیں۔ ایس کیو ایل کے سوالات، جسے ایک تجربہ کار DBA اصلاح کی تمام باریکیوں کے ساتھ لکھ سکتا ہے۔ ایس کیو ایل کے سوالات:

  1. بہترین کنکشن (شمولیت) اور نتائج کو فلٹر کرنا (کہاں)
  2. کنکشن اور گروپ کی شرائط کو استعمال کرنے میں بہت سی باریکیاں
  3. حالات کو بدلنے میں بہت سے تغیرات IN پر موجود ہےи اندر نہیں، <> آن موجود ہے
  4. عارضی ٹیبلز، CTE، ٹیبل متغیرات کے ذریعے نتائج کی انٹرمیڈیٹ کیشنگ
  5. جملے کا استعمال (اختیار) ہدایات اور ٹیبل اشارے کے ساتھ WITH (...)
  6. انتخاب کے دوران بے کار ڈیٹا ریڈنگ سے چھٹکارا حاصل کرنے کے ایک ذریعہ کے طور پر انڈیکسڈ ویوز کو استعمال کرنا

نتیجے کی اہم کارکردگی کی رکاوٹیں ایس کیو ایل کے سوالات مرتب کرتے وقت LINQ کے سوالات ہیں:

  1. ایک درخواست میں پورے ڈیٹا سلیکشن میکانزم کو اکٹھا کرنا
  2. کوڈ کے ایک جیسے بلاکس کو نقل کرنا، جو بالآخر متعدد غیر ضروری ڈیٹا کو پڑھنے کی طرف لے جاتا ہے۔
  3. کثیر اجزاء کی شرائط کے گروپ (منطقی "اور" اور "یا") - AND и OR, پیچیدہ حالات میں یکجا ہونا، اس حقیقت کی طرف لے جاتا ہے کہ مطلوبہ فیلڈز کے لیے موزوں غیر کلسٹرڈ اشاریہ جات رکھنے والا، بالآخر کلسٹرڈ انڈیکس کے خلاف اسکین کرنا شروع کر دیتا ہے (انڈیکس اسکین) شرائط کے گروپوں کے ذریعہ
  4. ذیلی سوالات کا گہرا گھونسلا تجزیہ کو بہت مشکل بنا دیتا ہے۔ ایس کیو ایل کے بیانات اور ڈویلپرز کی جانب سے استفسار کے منصوبے کا تجزیہ اور DBA

اصلاح کے طریقے۔

اب آئیے براہ راست اصلاح کے طریقوں کی طرف۔

1) اضافی اشاریہ کاری

مین سلیکشن ٹیبلز پر فلٹرز پر غور کرنا بہتر ہے، کیونکہ اکثر پوری استفسار ایک یا دو مین ٹیبلز (ایپلی کیشنز-لوگ-آپریشنز) اور شرائط کے ایک معیاری سیٹ (IsClosed, Canceled, Enabled, Status) کے ارد گرد بنایا جاتا ہے۔ شناخت شدہ نمونوں کے لیے مناسب انڈیکس بنانا ضروری ہے۔

یہ حل اس وقت سمجھ میں آتا ہے جب ان فیلڈز کو منتخب کرنے سے استفسار پر واپس کیے گئے سیٹ کو نمایاں طور پر محدود کر دیا جاتا ہے۔

مثال کے طور پر، ہمارے پاس 500000 درخواستیں ہیں۔ تاہم، صرف 2000 فعال درخواستیں ہیں۔ پھر صحیح طریقے سے منتخب کردہ انڈیکس ہمیں اس سے بچائے گا۔ انڈیکس اسکین ایک بڑی میز پر اور آپ کو غیر کلسٹرڈ انڈیکس کے ذریعے ڈیٹا کو تیزی سے منتخب کرنے کی اجازت دے گا۔

نیز، اشاریہ جات کی کمی کی نشاندہی استفسار کے منصوبوں کو پارس کرنے یا سسٹم ویو کے اعدادوشمار جمع کرنے کے اشارے کے ذریعے کی جا سکتی ہے۔ ایم ایس ایس کیو ایل سرور:

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

تمام ویو ڈیٹا میں مقامی اشاریہ جات کے استثناء کے ساتھ، گمشدہ اشاریہ جات کے بارے میں معلومات شامل ہیں۔

تاہم، اشاریہ جات اور کیشنگ اکثر خراب تحریر کے نتائج کا مقابلہ کرنے کے طریقے ہیں۔ LINQ کے سوالات и ایس کیو ایل کے سوالات.

جیسا کہ زندگی کی سخت مشق سے پتہ چلتا ہے، کاروبار کے لیے بعض اوقات مقررہ تاریخوں تک کاروباری خصوصیات کو نافذ کرنا ضروری ہوتا ہے۔ اور اس وجہ سے، بھاری درخواستوں کو اکثر کیشنگ کے ساتھ پس منظر میں منتقل کیا جاتا ہے۔

یہ جزوی طور پر جائز ہے، کیونکہ صارف کو ہمیشہ تازہ ترین ڈیٹا کی ضرورت نہیں ہوتی ہے اور صارف کے انٹرفیس کی ردعمل کی ایک قابل قبول سطح ہوتی ہے۔

یہ نقطہ نظر کاروباری ضروریات کو حل کرنے کی اجازت دیتا ہے، لیکن بالآخر مسائل کے حل میں تاخیر کرکے معلوماتی نظام کی کارکردگی کو کم کر دیتا ہے۔

یہ بھی یاد رکھنے کے قابل ہے کہ شامل کرنے کے لیے ضروری اشاریہ جات کی تلاش کے عمل میں، تجاویز ایم ایس ایس کیو ایل۔ اصلاح غلط ہو سکتی ہے، بشمول درج ذیل شرائط کے تحت:

  1. اگر پہلے ہی فیلڈز کے ایک جیسے سیٹ کے ساتھ اشاریہ جات موجود ہیں۔
  2. اگر ٹیبل میں فیلڈز کو اشاریہ سازی کی پابندیوں کی وجہ سے انڈیکس نہیں کیا جاسکتا ہے (مزید تفصیل سے بیان کیا گیا ہے) یہاں).

2) صفات کو ایک نئی صفت میں ضم کرنا

بعض اوقات ایک ٹیبل سے کچھ فیلڈز، جو شرائط کے گروپ کی بنیاد کے طور پر کام کرتے ہیں، ایک نیا فیلڈ متعارف کروا کر تبدیل کیا جا سکتا ہے۔

یہ خاص طور پر اسٹیٹس فیلڈز کے لیے درست ہے، جو عام طور پر بٹ یا انٹیجر ٹائپ ہوتے ہیں۔

: مثال کے طور پر

بند = 0 اور منسوخ = 0 اور فعال = 0 کی طرف سے تبدیل کیا جاتا ہے حیثیت = 1.

یہ وہ جگہ ہے جہاں انٹیجر اسٹیٹس انتساب متعارف کرایا جاتا ہے تاکہ یہ یقینی بنایا جاسکے کہ یہ اسٹیٹس ٹیبل میں آباد ہیں۔ اگلا، اس نئے وصف کو ترتیب دیا گیا ہے۔

یہ کارکردگی کے مسئلے کا ایک بنیادی حل ہے، کیونکہ ہم غیر ضروری حساب کے بغیر ڈیٹا تک رسائی حاصل کرتے ہیں۔

3) منظر کو مادی بنانا

بدقسمتی سے، میں LINQ کے سوالات عارضی میزیں، CTEs، اور ٹیبل متغیرات کو براہ راست استعمال نہیں کیا جا سکتا۔

تاہم، اس کیس کے لیے بہتر بنانے کا ایک اور طریقہ ہے - انڈیکسڈ آراء۔

حالت گروپ (اوپر کی مثال سے) بند = 0 اور منسوخ = 0 اور فعال = 0 (یا اسی طرح کے دیگر حالات کا ایک سیٹ) ان کو انڈیکسڈ ویو میں استعمال کرنے کا ایک اچھا آپشن بن جاتا ہے، ایک بڑے سیٹ سے ڈیٹا کے ایک چھوٹے سے ٹکڑے کو کیش کرنا۔

لیکن ایک نقطہ نظر کو عملی جامہ پہناتے وقت کئی پابندیاں ہیں:

  1. ذیلی سوالات، شقوں کا استعمال موجود ہے کا استعمال کرتے ہوئے تبدیل کیا جانا چاہئے شمولیت
  2. آپ جملے استعمال نہیں کر سکتے UNION, یونین سب, رعایت, انٹرسیکٹ
  3. آپ ٹیبل کے اشارے اور شقیں استعمال نہیں کر سکتے اختیار
  4. سائیکل کے ساتھ کام کرنے کا کوئی امکان نہیں ہے۔
  5. مختلف جدولوں سے ڈیٹا کو ایک منظر میں ظاہر کرنا ناممکن ہے۔

یہ یاد رکھنا ضروری ہے کہ اشاریہ شدہ نقطہ نظر کو استعمال کرنے کا حقیقی فائدہ صرف اس کی اصل میں اشاریہ سازی سے ہی حاصل کیا جا سکتا ہے۔

لیکن کسی منظر کو کال کرتے وقت، یہ اشاریہ جات استعمال نہیں کیے جاسکتے ہیں، اور انہیں واضح طور پر استعمال کرنے کے لیے، آپ کو وضاحت کرنا ہوگی کے ساتھ (NOEXPAND).

جب سے میں LINQ کے سوالات ٹیبل کے اشارے کی وضاحت کرنا ناممکن ہے، لہذا آپ کو ایک اور نمائندگی بنانا ہوگی - درج ذیل شکل کا "ریپر":

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

4) ٹیبل کے افعال کا استعمال

اکثر میں LINQ کے سوالات ذیلی سوالات کے بڑے بلاکس یا ایک پیچیدہ ڈھانچے کے ساتھ آراء کا استعمال کرتے ہوئے بلاکس ایک انتہائی پیچیدہ اور سب سے زیادہ قابل عمل ڈھانچہ کے ساتھ ایک حتمی استفسار بناتے ہیں۔

میں ٹیبل کے افعال استعمال کرنے کے کلیدی فوائد LINQ کے سوالات:

  1. قابلیت، جیسا کہ آراء کے معاملے میں، کسی چیز کے طور پر استعمال اور مخصوص کرنے کی، لیکن آپ ان پٹ پیرامیٹرز کا ایک سیٹ پاس کر سکتے ہیں:
    فنکشن سے (@param1, @param2 ...)
    نتیجے کے طور پر، لچکدار ڈیٹا سیمپلنگ حاصل کی جا سکتی ہے۔
  2. ٹیبل فنکشن استعمال کرنے کی صورت میں، ایسی کوئی سخت پابندیاں نہیں ہیں جیسا کہ اوپر بیان کردہ انڈیکسڈ ویوز کے معاملے میں:
    1. ٹیبل کے اشارے:
      کے ذریعے لنک آپ اس بات کی وضاحت نہیں کر سکتے کہ کون سے اشاریہ جات استعمال کیے جائیں اور استفسار کرتے وقت ڈیٹا آئسولیشن لیول کا تعین کریں۔
      لیکن فنکشن میں یہ صلاحیتیں ہیں۔
      فنکشن کے ساتھ، آپ کافی مستقل استفسار کا منصوبہ حاصل کر سکتے ہیں، جہاں اشاریہ جات کے ساتھ کام کرنے کے قواعد اور ڈیٹا آئسولیشن لیولز کی وضاحت کی گئی ہے۔
    2. فنکشن کا استعمال انڈیکسڈ ویوز کے مقابلے میں، حاصل کرنے کی اجازت دیتا ہے:
      • پیچیدہ ڈیٹا سیمپلنگ منطق (یہاں تک کہ لوپس کا استعمال کرتے ہوئے)
      • بہت سے مختلف جدولوں سے ڈیٹا حاصل کرنا
      • کے استعمال UNION и موجود ہے

  3. پیش کرتے ہیں۔ اختیار بہت مفید ہے جب ہمیں کنکرنسی کنٹرول فراہم کرنے کی ضرورت ہوتی ہے۔ OPTION(MAXDOP N)، استفسار پر عمل درآمد کی منصوبہ بندی کا حکم۔ مثال کے طور پر:
    • آپ استفسار کے پلان کی زبردستی دوبارہ تخلیق کی وضاحت کر سکتے ہیں۔ آپشن (دوبارہ مرتب کریں)
    • آپ اس بات کی وضاحت کر سکتے ہیں کہ آیا استفسار کے پلان کو استفسار میں بیان کردہ جوائن آرڈر کو استعمال کرنے پر مجبور کرنا ہے۔ آپشن (زبردستی آرڈر)

    کے بارے میں مزید تفصیلات اختیار بیان کیا یہاں.

  4. سب سے تنگ اور انتہائی مطلوبہ ڈیٹا سلائس کا استعمال:
    بڑے ڈیٹا سیٹس کو کیچز میں اسٹور کرنے کی ضرورت نہیں ہے (جیسا کہ انڈیکسڈ ویوز کا معاملہ ہے)، جہاں سے آپ کو پیرامیٹر کے حساب سے ڈیٹا فلٹر کرنے کی ضرورت ہے۔
    مثال کے طور پر، ایک میز ہے جس کا فلٹر کہاں تین شعبوں کا استعمال کیا جاتا ہے (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])
));

اس منظر میں ایک پیچیدہ ڈھانچہ ہے: اس میں ذیلی سوالات کے جوڑ ہوتے ہیں اور چھانٹنے کا استعمال ہوتا ہے۔ ڈسٹنکٹ، جو عام طور پر کافی وسائل پر مبنی آپریشن ہے۔

OperativeQuestions سے ایک نمونہ تقریباً دس ہزار ریکارڈ ہے۔

اس استفسار کے ساتھ بنیادی مسئلہ یہ ہے کہ بیرونی استفسار کے ریکارڈز کے لیے، ایک اندرونی ذیلی استفسار [OperativeQuestions] منظر پر عمل میں لایا جاتا ہے، جو کہ [Email] = @p__linq__0 کے لیے ہمیں آؤٹ پٹ سلیکشن کو محدود کرنے کی اجازت دیتا ہے (بذریعہ موجود ہے) سینکڑوں ریکارڈز تک۔

اور ایسا لگتا ہے کہ ذیلی استفسار کو [ای میل] = @p__linq__0 کے ذریعہ ایک بار ریکارڈ کا حساب لگانا چاہئے، اور پھر ان سو ریکارڈز کو سوالات کے ساتھ آئی ڈی کے ذریعہ منسلک کیا جانا چاہئے، اور استفسار تیز ہوگا۔

درحقیقت، تمام جدولوں کا ایک سلسلہ وار تعلق ہے: آپریٹو سوالات سے آئی ڈی کے ساتھ آئی ڈی کے سوالات کی خط و کتابت کی جانچ کرنا، اور ای میل کے ذریعے فلٹر کرنا۔

درحقیقت، درخواست تمام دسیوں ہزار آپریٹو سوالات کے ریکارڈ کے ساتھ کام کرتی ہے، لیکن ای میل کے ذریعے صرف دلچسپی کا ڈیٹا درکار ہے۔

آپریٹو سوالات کا متن دیکھیں:

درخواست نمبر 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 کے ذریعے اندراجات کو کیش کرنا ہے۔

ڈیٹا بیس میں ٹیبل فنکشن [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 کو 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 ایم ایس کے بجائے ہمیں 8 ایم ایس ملے۔

واضح فوائد سے ہم یہ بھی حاصل کرتے ہیں:

  1. پڑھنے کے بوجھ میں عمومی کمی،
  2. بلاک ہونے کے امکانات میں نمایاں کمی
  3. مسدود کرنے کے اوسط وقت کو قابل قبول اقدار تک کم کرنا

آؤٹ پٹ

ڈیٹا بیس کالوں کی اصلاح اور ٹھیک ٹیوننگ ایم ایس ایس کیو ایل۔ کے ذریعے لنک ایک مسئلہ ہے جو حل کیا جا سکتا ہے.

اس کام میں توجہ اور مستقل مزاجی بہت ضروری ہے۔

عمل کے آغاز میں:

  1. اس ڈیٹا کو چیک کرنا ضروری ہے جس کے ساتھ درخواست کام کرتی ہے (اقدار، ڈیٹا کی منتخب اقسام)
  2. اس ڈیٹا کی مناسب اشاریہ سازی کریں۔
  3. میزوں کے درمیان جوائننگ کنڈیشنز کی درستگی کو چیک کریں۔

اگلی اصلاحی تکرار سے پتہ چلتا ہے:

  1. درخواست کی بنیاد اور بنیادی درخواست کے فلٹر کی وضاحت کرتا ہے۔
  2. اسی طرح کے استفسار کے بلاکس کو دہرانا اور حالات کے تقاطع کا تجزیہ کرنا
  3. کے لیے SSMS یا دیگر GUI میں SQL سرور خود کو بہتر بناتا ہے SQL استفسار (ایک انٹرمیڈیٹ ڈیٹا اسٹوریج مختص کرنا، اس سٹوریج کا استعمال کرتے ہوئے نتیجے میں استفسار کرنا (کئی ہو سکتی ہے))
  4. آخری مرحلے پر، نتیجے کے طور پر ایک بنیاد کے طور پر لے SQL استفسار، ڈھانچہ دوبارہ تعمیر کیا جا رہا ہے۔ LINQ استفسار

نتیجے میں LINQ استفسار شناخت شدہ بہترین کے ڈھانچے میں یکساں ہونا چاہئے۔ SQL استفسار پوائنٹ 3 سے

اعترافات

ساتھیوں کا بہت شکریہ jobgemws и alex_ozr کمپنی سے فورٹس اس مواد کی تیاری میں مدد کے لیے۔

ماخذ: www.habr.com

نیا تبصرہ شامل کریں