[英]Linq query taking too long to process results
我有3張桌子
我正在嘗試使用以下查詢從這 3 個表中獲取數據:.. ERPApp 表與其他 2 個表處於不同的上下文中,這就是我使用 2 個查詢的原因
var res = (from s in ERPDB.ERPEntrys
join t in ERPDB.ERPEntryTypes
on s.EntryTypeID equals t.EntryTypeID
where s.UserIDAdded == '250176'
select new {s.EntryTypeID, s.DateAdded, t.EntryTypeName, s.AppID }).OrderByDescending(d => d.DateAdded).Take(10).ToArray();
var erpResult = (from a in APPDB.ERPApps.AsEnumerable()
join b in res on a.AppId equals b.AppId
select new ERPInfo
{
EntryId = b.EntryID,
EntryType = b.EntryTypeName,
ERPApp = a.ApplicationName,
DateAdded = b.DateAdded
}).ToList();
我得到了想要的結果,但第二個查詢需要將近 4 分鍾的時間來處理並將結果返回到可變的 erpResult 中……有關如何解決此性能問題的任何幫助?
先說答案:
var res = (from s in ERPDB.ERPEntries
join t in ERPDB.ERPEntryTypes
on s.EntryTypeID equals t.EntryTypeID
where s.UserIdAdded == "250176"
select new { s.EntryID, s.EntryTypeID, s.DateAdded, t.EntryTypeName, s.AppId })
.OrderByDescending(d => d.DateAdded).Take(10).ToArray();
/* Which immediately executes:
exec sp_executesql N'SELECT TOP (10) [t0].[EntryID], [t0].[EntryTypeID],
[t0].[DateAdded], [t1].[EntryTypeName], [t0].[AppId]
FROM [dbo].[ERPEntry] AS [t0]
INNER JOIN [dbo].[ERPEntryType] AS [t1] ON [t0].[EntryTypeID] = [t1].
[EntryTypeID]
WHERE [t0].[UserIdAdded] = @p0
ORDER BY [t0].[DateAdded] DESC',N'@p0 varchar(8000)',@p0='250176'
*/
// Get the distinct AppID values in res
// Executes in memory
var distinctApps = (from r in res select r.AppId).Distinct();
// Query APPDB with the distinct values
var matchingApps = (from a in APPDB.ERPApps where distinctApps
.Contains(a.AppId) select new { a.AppId, a.ApplicationName }).ToArray();
/* Which immediately executes this efficient query:
exec sp_executesql N'SELECT [t0].[AppId], [t0].[ApplicationName]
FROM [dbo].[ERPApp] AS [t0]
WHERE [t0].[AppId] IN (@p0, @p1, @p2, @p3)',N'@p0 bigint,@p1 bigint,@p2
bigint,@p3 bigint',@p0=101,@p1=123,@p2=125,@p3=129
*/
var erpResultWithAppNames = (from a in matchingApps
join b in res on a.AppId equals b.AppId
select new
{
EntryId = b.EntryID,
EntryType = b.EntryTypeName,
ERPApp = a.ApplicationName,
DateAdded = b.DateAdded
}).ToList();
額外說明:
正如評論中已經提到的,在APPDB.ERPApps
表上調用.AsEnumerable()
會導致整個表作為對象加載到內存中。
事實:
您必須將 25.000 行加載到內存中(並將它們轉換為對象),
您不僅加載了 25.000 行。 您正在加載 25.000 x 173 個單元格並創建 25.000 個對象,每個對象具有 173 個字段。
如果您可以只加載您需要的兩個字段(AppId 和 ApplicationName)而不是所有 173 個字段(以及它們擁有的任何數據),則性能會提高,但考慮到您要實現的目標,效率仍然很低。
當前的性能問題部分是由於將整個表及其所有 173 個字段傳輸到您的服務器,部分原因是將所有這些行映射到對象,將字段映射到屬性。 每個的影響都可以作為進一步的研究來衡量。
Linq 到 SQL。 使用 SqlProfiler 檢查時:
from a in APPDB.ERPApps.AsEnumerable() join b ...
// PROFILED QUERY:
SELECT [t0].[AppId], [t0].[ApplicationName], [t0].[Field1], [t0].[Field2],
[t0].[Field3], [t0].[Field4], [t0].[Field5], [t0].[Field6], [t0].[Field7],
[t0].[Field8], [t0].[Field9], ... ... ... ... [t0].[Field176], [t0].[Field173],
FROM [dbo].[ERPApp] AS [t0]
但:
var erpResult = (from a in APPDB.ERPApps
select new { AppId = a.AppId, ApplicationName = a.ApplicationName }
).ToArray();
// PROFILED QUERY:
SELECT [t0].[AppId], [t0].[ApplicationName]
FROM [dbo].[ERPApp] AS [t0]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.