मेरे पास बहुत भारी 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]
}
पृष्ठभूमि में निष्पादित एसक्यूएल क्या है? क्वेरी प्लान कैसा दिखता है? – Heinzi
मैं संग्रहीत प्रक्रिया में सभी रिकॉर्ड्स का चयन करते हुए उत्सुक होगा, इसे IMultilpleResults के साथ बुलाकर, स्मृति में शामिल होने से तेज़ नहीं होगा। – Joe
क्या आप वाकई एक कथन में यह सब कुछ करते हैं (और चयनित प्रति पंक्ति अतिरिक्त विवरण नहीं) - 100% सुनिश्चित नहीं है कि यह चुनिंदा नए परिदृश्य में संभव है तो ऐसा करें जैसे @Heinzi ने कहा: आपको एसक्यूएल देखना होगा जो प्रोफाइलर का उपयोग करके उत्पन्न होता है या अपना डेटाैकेंटेक्स्ट – Pleun