sql - يستمر استعلام سكل قيد التشغيل لفترة طويلة جدا إذا لم يتم العثور على عبارة البحث



sql-server linq (2)

يمكنك بالفعل تبسيط طلب البحث مثل هذا؛):

int start=page * recordsInPage;

var inner = (from user in db.Users
            where user.Name.Contains(name) && !user.Deleted && user.AppearInSearch
            orderby user.Verified descending
            select  new
                   {
                     Name = user.Name,
                     Verified = user.Verified,
                     PhotoURL = user.PhotoURL,
                     UserID = user.Id,
                     Subdomain = user.Subdomain,
                     Deleted=user.Deleted,
                     AppearInSearch = user.AppearInSearch
                   }
             ).Skip(start).Take(recordsInPage);

return await inner.ToListAsync();

إذا كان لديك مشكلة في الأداء، حاول إنشاء إجراء مخزن مع سكل واستخدامه مع الكيان الإطار.

https://rueisnom.com

في بلدي أزور استضافت ASP.NET الموقع الأساسي لدي جدول من المستخدمين وقمت بتنفيذ البحث على النحو التالي:

    var inner = from user in db.Users
             select  new
             {
                 Name = user.Name,
                 Verified = user.Verified,
                 PhotoURL = user.PhotoURL,
                 UserID = user.Id,
                 Subdomain = user.Subdomain,
                 Deleted=user.Deleted,
                 AppearInSearch = user.AppearInSearch
             };
    return await inner.Where(u=>u.Name.Contains(name)&& !u.Deleted && u.AppearInSearch)
                                    .OrderByDescending(u => u.Verified)
                                    .Skip(page * recordsInPage)
                                    .Take(recordsInPage)
                                    .Select(u => new UserSearchResult()
                                    {
                                        Name = u.Name,
                                        Verified = u.Verified,
                                        PhotoURL = u.PhotoURL,
                                        UserID = u.UserID,
                                        Subdomain = u.Subdomain
                                    }).ToListAsync();

هذا يترجم إلى عبارة سكل مشابهة لما يلي:

SELECT [t].[Name], [t].[Verified],
       [t].[PhotoURL], [t].[Id], 
       [t].[Subdomain], [t].[Deleted], 
       [t].[AppearInSearch]  
FROM (      
        SELECT [user0].[Name], [user0].[Verified], 
               [user0].[PhotoURL], [user0].[Id], 
               [user0].[Subdomain], [user0].[Deleted], 
               [user0].[AppearInSearch]      
        FROM [AspNetUsers] AS [user0]
        WHERE (((CHARINDEX('khaled', [user0].[Name]) > 0) OR ('khaled' = N'')) 
          AND ([user0].[Deleted] = 0)) 
          AND ([user0].[AppearInSearch] = 1)      
        ORDER BY [user0].[Verified] DESC      
        OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY  ) AS [t]

إذا كانت عبارة البحث متاحة في قاعدة البيانات، يتم الحصول على النتيجة في أقل من ثانية. ومع ذلك، إذا لم يتم العثور على الاستعلام يعمل لفترة طويلة جدا (لقد رأيت ذلك مرة واحدة تصل إلى 48 ثانية).

هذا يؤثر بشكل كبير على الأداء عند نشر هذه الميزة إلى الإنترنت.

يمكنك التفضل تشير إلى وسيلة لحل هذه المسألة؟

شكرا لكم

تحديث: تتم متابعة هذه المشكلة هنا: إفراغ اسم تسجيل الدخول عند عرض sys.processes


Answer #1

يجب أن يستخدم سكل سيرفر مسح للبحث عن صفوف مطابقة .Contains جملة. ليس هناك اي طريقة حول هذا.

ومع ذلك، إذا خفضنا كمية البيانات التي ملقم سكل لمسح، ونحن سوف تسريع الاستعلام.

تغطية الفهرس الذي تمت تصفيته

الفهرس هو "تغطية" إذا كان يحتوي على كافة البيانات المطلوبة لإرجاعها في الاستعلام.

CREATE INDEX IX_User_Name_filtered ON USER ([Verified], [Name]) 
INCLUDE ( [PhotoURL], [Id], [Subdomain], [Deleted], [AppearInSearch]  ) 
WHERE [AppearInSearch]=1 AND [Deleted]=0

هذا المؤشر من المرجح أن يكون أصغر بكثير من الجدول الأصلي، لذلك حتى لو كان هناك حاجة إلى المسح الضوئي، وسوف يكون أسرع.

اعتمادا على الخطة التي تم إنشاؤها، قد يكون هذا الفهرس خيارا أفضل. فإنه لا يتضمن الأعمدة الإضافية وسوف تكون أصغر لا يزال. سيكون الاختبار مطلوبا لتحديد أفضل خيار.

CREATE INDEX IX_User_Name_filtered ON USER ([Verified], [Name]) 
WHERE [AppearInSearch]=1 AND [Deleted]=0




asp.net-core