2011-09-06 11 views
8

मेरे पास बहुत भारी LINQ-to-SQL क्वेरी है, जो अज्ञात प्रकार को वापस करने के लिए विभिन्न तालिकाओं पर कई जुड़ती है। समस्या यह है कि यदि पंक्तियों की मात्रा काफी बड़ी है (> 200), तो क्वेरी बहुत धीमी हो जाती है और समय समाप्त हो जाती है। मुझे पता है कि मैं डेटा संदर्भ टाइमआउट सेटिंग बढ़ा सकता हूं, लेकिन यह एक अंतिम उपाय है।LINQ-to-SQL क्वेरीज़ को अनुकूलित करना

मैं सोच रहा हूं कि अगर मैं इसे विभाजित करता हूं तो मेरी क्वेरी बेहतर काम करेगी, और LINQ-to-Objects क्वेरी के रूप में मेरी तुलना करें ताकि मैं संभवतः प्रसंस्करण शक्ति को अधिकतम करने के लिए PLINQ का उपयोग भी कर सकूं। लेकिन मैं यह मेरे लिए एक विदेशी अवधारणा हूं, और मैं अपने सिर को इस बारे में नहीं समझ सकता कि मैं इसे कैसे विभाजित करूं। क्या कोई सलाह दे सकते हैं? मैं कोड के लिए मेरे लिए लिखे जाने के लिए नहीं कह रहा हूं, बस कुछ सामान्य मार्गदर्शन यह है कि मैं इसे कैसे सुधार सकता हूं, यह बहुत अच्छा होगा।

नोट मैंने यह सुनिश्चित किया है कि डेटाबेस में सभी सही कुंजी हैं जिन पर मैं शामिल हो रहा हूं, और मैंने यह सुनिश्चित किया है कि ये कुंजी अद्यतित हैं।

क्वेरी नीचे है:

var cons = (from c in dc.Consignments 
      join p in dc.PODs on c.IntConNo equals p.Consignment into pg 
      join d in dc.Depots on c.DeliveryDepot equals d.Letter 
      join sl in dc.Accounts on c.Customer equals sl.LegacyID 
      join ss in dc.Accounts on sl.InvoiceAccount equals ss.LegacyID 
      join su in dc.Accounts on c.Subcontractor equals su.Name into sug 
      join sub in dc.Accountsubbies on ss.ID equals sub.AccountID into subg 
      where (sug.FirstOrDefault() == null 
       || sug.FirstOrDefault().Customer == false) 
      select new 
      { 
       ID = c.ID, 
       IntConNo = c.IntConNo, 
       LegacyID = c.LegacyID, 
       PODs = pg.DefaultIfEmpty(), 
       TripNumber = c.TripNumber, 
       DropSequence = c.DropSequence, 
       TripDate = c.TripDate, 
       Depot = d.Name, 
       CustomerName = c.Customer, 
       CustomerReference = c.CustomerReference, 
       DeliveryName = c.DeliveryName, 
       DeliveryTown = c.DeliveryTown, 
       DeliveryPostcode = c.DeliveryPostcode, 
       VehicleText = c.VehicleReg + c.Subcontractor, 
       SubbieID = sug.DefaultIfEmpty().FirstOrDefault().ID.ToString(), 
       SubbieList = subg.DefaultIfEmpty(), 
       ScanType = ss.PODScanning == null ? 0 : ss.PODScanning 
      }); 

यहाँ उत्पन्न एसक्यूएल के रूप में अनुरोध है:

{SELECT [t0].[ID], [t0].[IntConNo], [t0].[LegacyID], [t6].[test], [t6].[ID] AS [ID2], [t6].[Consignment], [t6].[Status], [t6].[NTConsignment], [t6].[CustomerRef], [t6].[Timestamp], [t6].[SignedBy], [t6].[Clause], [t6].[BarcodeNumber], [t6].[MainRef], [t6].[Notes], [t6].[ConsignmentRef], [t6].[PODedBy], (
    SELECT COUNT(*) 
    FROM (
     SELECT NULL AS [EMPTY] 
     ) AS [t10] 
    LEFT OUTER JOIN (
     SELECT NULL AS [EMPTY] 
     FROM [dbo].[PODs] AS [t11] 
     WHERE [t0].[IntConNo] = [t11].[Consignment] 
     ) AS [t12] ON 1=1 
    ) AS [value], [t0].[TripNumber], [t0].[DropSequence], [t0].[TripDate], [t1].[Name] AS [Depot], [t0].[Customer] AS [CustomerName], [t0].[CustomerReference], [t0].[DeliveryName], [t0].[DeliveryTown], [t0].[DeliveryPostcode], [t0].[VehicleReg] + [t0].[Subcontractor] AS [VehicleText], CONVERT(NVarChar,(
    SELECT [t16].[ID] 
    FROM (
     SELECT TOP (1) [t15].[ID] 
     FROM (
      SELECT NULL AS [EMPTY] 
      ) AS [t13] 
     LEFT OUTER JOIN (
      SELECT [t14].[ID] 
      FROM [dbo].[Account] AS [t14] 
      WHERE [t0].[Subcontractor] = [t14].[Name] 
      ) AS [t15] ON 1=1 
     ORDER BY [t15].[ID] 
     ) AS [t16] 
    )) AS [SubbieID], 
    (CASE 
     WHEN [t3].[PODScanning] IS NULL THEN @p0 
     ELSE [t3].[PODScanning] 
    END) AS [ScanType], [t3].[ID] AS [ID3] 
FROM [dbo].[Consignments] AS [t0] 
INNER JOIN [dbo].[Depots] AS [t1] ON [t0].[DeliveryDepot] = [t1].[Letter] 
INNER JOIN [dbo].[Account] AS [t2] ON [t0].[Customer] = [t2].[LegacyID] 
INNER JOIN [dbo].[Account] AS [t3] ON [t2].[InvoiceAccount] = [t3].[LegacyID] 
LEFT OUTER JOIN ((
     SELECT NULL AS [EMPTY] 
     ) AS [t4] 
    LEFT OUTER JOIN (
     SELECT 1 AS [test], [t5].[ID], [t5].[Consignment], [t5].[Status], [t5].[NTConsignment], [t5].[CustomerRef], [t5].[Timestamp], [t5].[SignedBy], [t5].[Clause], [t5].[BarcodeNumber], [t5].[MainRef], [t5].[Notes], [t5].[ConsignmentRef], [t5].[PODedBy] 
     FROM [dbo].[PODs] AS [t5] 
     ) AS [t6] ON 1=1) ON [t0].[IntConNo] = [t6].[Consignment] 
WHERE ((NOT (EXISTS(
    SELECT TOP (1) NULL AS [EMPTY] 
    FROM [dbo].[Account] AS [t7] 
    WHERE [t0].[Subcontractor] = [t7].[Name] 
    ORDER BY [t7].[ID] 
    ))) OR (NOT (((
    SELECT [t9].[Customer] 
    FROM (
     SELECT TOP (1) [t8].[Customer] 
     FROM [dbo].[Account] AS [t8] 
     WHERE [t0].[Subcontractor] = [t8].[Name] 
     ORDER BY [t8].[ID] 
     ) AS [t9] 
    )) = 1))) AND ([t2].[Customer] = 1) AND ([t3].[Customer] = 1) 
ORDER BY [t0].[ID], [t1].[ID], [t2].[ID], [t3].[ID], [t6].[ID] 
} 
+4

पृष्ठभूमि में निष्पादित एसक्यूएल क्या है? क्वेरी प्लान कैसा दिखता है? – Heinzi

+0

मैं संग्रहीत प्रक्रिया में सभी रिकॉर्ड्स का चयन करते हुए उत्सुक होगा, इसे IMultilpleResults के साथ बुलाकर, स्मृति में शामिल होने से तेज़ नहीं होगा। – Joe

+0

क्या आप वाकई एक कथन में यह सब कुछ करते हैं (और चयनित प्रति पंक्ति अतिरिक्त विवरण नहीं) - 100% सुनिश्चित नहीं है कि यह चुनिंदा नए परिदृश्य में संभव है तो ऐसा करें जैसे @Heinzi ने कहा: आपको एसक्यूएल देखना होगा जो प्रोफाइलर का उपयोग करके उत्पन्न होता है या अपना डेटाैकेंटेक्स्ट – Pleun

उत्तर

3

उच्च शामिल उपठेकेदार ले जाने का प्रयास है और इसके साथ-साथ जहां खंड धक्का। इस तरह आप अनावश्यक रूप से शामिल नहीं हो रहे हैं जो अंत में विफल हो जाएंगे। मैं उप-कंट्रोलर आईडी के लिए भी चयन को संशोधित करता हूं, इसलिए आपको संभावित रूप से शून्य मान का आईडी नहीं मिलता है।

var cons = (from c in dc.Consignments 
      join su in dc.Accounts on c.Subcontractor equals su.Name into sug 
      where (sug.FirstOrDefault() == null || sug.FirstOrDefault().Customer == false) 
      join p in dc.PODs on c.IntConNo equals p.Consignment into pg 
      join d in dc.Depots on c.DeliveryDepot equals d.Letter 
      join sl in dc.Accounts on c.Customer equals sl.LegacyID 
      join ss in dc.Accounts on sl.InvoiceAccount equals ss.LegacyID     
      join sub in dc.Accountsubbies on ss.ID equals sub.AccountID into subg 
      let firstSubContractor = sug.DefaultIfEmpty().FirstOrDefault() 
      select new 
      { 
          ID = c.ID, 
          IntConNo = c.IntConNo, 
          LegacyID = c.LegacyID, 
          PODs = pg.DefaultIfEmpty(), 
          TripNumber = c.TripNumber, 
          DropSequence = c.DropSequence, 
          TripDate = c.TripDate, 
          Depot = d.Name, 
          CustomerName = c.Customer, 
          CustomerReference = c.CustomerReference, 
          DeliveryName = c.DeliveryName, 
          DeliveryTown = c.DeliveryTown, 
          DeliveryPostcode = c.DeliveryPostcode, 
          VehicleText = c.VehicleReg + c.Subcontractor, 
          SubbieID = firstSubContractor == null ? "" : firstSubContractor.ID.ToString(), 
          SubbieList = subg.DefaultIfEmpty(), 
          ScanType = ss.PODScanning == null ? 0 : ss.PODScanning 
       }); 
संबंधित मुद्दे