简体   繁体   English

Linq 查询处理结果的时间太长

[英]Linq query taking too long to process results

I have 3 tables我有3张桌子

  • ERPEntry ERP条目
  • ERPEntryType ERP条目类型
  • ERPApp应用程序

I am trying to get data from these 3 tables using the below queries:.. The table ERPApp is in different context than the other 2 tables, that is the reason i am using 2 queries我正在尝试使用以下查询从这 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();

I got the desired result but the 2nd query is taking almost 4 minutes to process and return result into varibale erpResult... any help on how can i resolve this performace issue ?我得到了想要的结果,但第二个查询需要将近 4 分钟的时间来处理并将结果返回到可变的 erpResult 中……有关如何解决此性能问题的任何帮助?

First, the answer:先说答案:

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();

Extra notes:额外说明:

As already mentioned in the comments, the call to .AsEnumerable() on the APPDB.ERPApps table causes the whole table to be loaded into memory as objects.正如评论中已经提到的,在APPDB.ERPApps表上调用.AsEnumerable()会导致整个表作为对象加载到内存中。

Facts:事实:

  1. You had to load 25.000 rows into memory (and convert them to objects),您必须将 25.000 行加载到内存中(并将它们转换为对象),

  2. You are not only loading 25.000 rows.您不仅加载了 25.000 行。 You are loading 25.000 x 173 cells and create 25.000 objects with 173 fields each.您正在加载 25.000 x 173 个单元格并创建 25.000 个对象,每个对象具有 173 个字段。

  3. if you could just load the two fields you need (AppId and ApplicationName) instead of all the 173 fields (with whatever data they have) the performance would improve, but would still be inefficient considering what you are trying to achieve.如果您可以只加载您需要的两个字段(AppId 和 ApplicationName)而不是所有 173 个字段(以及它们拥有的任何数据),则性能会提高,但考虑到您要实现的目标,效率仍然很低。

  4. The current performance problem is in part due to transferring the whole table with all its 173 fields to your server, and in part to mapping all these rows to objects and fields to properties.当前的性能问题部分是由于将整个表及其所有 173 个字段传输到您的服务器,部分原因是将所有这些行映射到对象,将字段映射到属性。 The impact of each can be measured as further research.每个的影响都可以作为进一步的研究来衡量。

Linq To SQL. Linq 到 SQL。 When checked with SqlProfiler:使用 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]

But:但:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM