【问题标题】:Linq to Entities Query OptimisationLinq to Entity 查询优化
【发布时间】:2014-06-19 13:04:29
【问题描述】:

我有一个 LINQ 查询,它将根据票证是否满足一些条件来选择票证。查询本身运行良好并且工作正常,但我担心随着可能返回的数量增加,它会变得明显更糟。

任何人都可以提出改进或优化此查询以更快/更好地运行的方法吗?我是否在违反标准做法做错了什么?

这是查询。我换了几个名字。我认为select new 语句中的select 也是一个问题。

var attentionObj = (from c in context.SupportTicketEntities
                    where
                    c.StatusID != 3 && 
                    ((c.IsAllocated == false)    // not allocated
                    || (c.FlaggedForAssist == true && c.AllocatedToEmployeeID == empId)     // is flagged for assist
                    || ((from d in c.SupportTicketDatas
                         where c.AllocatedToEmployeeID == empId
                         && c.FogBugzAttachments.Count == 0
                         orderby d.TimeStamp descending
                         select d.TimeStamp).FirstOrDefault() < warningDt)   // ticket not replied to
                    || ((from e in c.SupportTicketDatas
                         where c.AllocatedToEmployeeID == empId
                         orderby e.TimeStamp descending
                         select e).FirstOrDefault().RaisedByUser == true)   // customer has replied
                    || (c.IsEscalated == true))  // ticket escalated
                    select new
                    {
                        RefID = c.RefID,
                        TicketID = c.SupportTicketID,
                        ClientCompany = c.ClientData.Company,
                        IsAllocated = c.IsAllocated,
                        DateLogged = c.DateLogged,
                        IsFlagged = c.FlaggedForAssist,
                        NeedsReply = (from d in c.SupportTicketDatas
                                      orderby d.TimeStamp descending
                                      select d.TimeStamp).FirstOrDefault() < warningDt,
                        CustReply = (from e in c.SupportTicketDatas
                                     orderby e.TimeStamp descending
                                     select e).FirstOrDefault().RaisedByUser == true,
                        IsEscalated = c.IsEscalated
                    }).ToArray();

编辑:所以我创建了一个存储过程,虽然我不是最擅长 SQL。这样可以吗?

@empId int,
@warningDt datetime
AS
SELECT * FROM SupportTickets
WHERE StatusID != 3
AND IsAllocated = 0
UNION
SELECT * FROM SupportTickets
WHERE StatusID != 3
AND FlaggedForAssist = 1
AND AllocatedToEmployeeID = @empId
UNION
SELECT * FROM SupportTickets
WHERE StatusID != 3
AND AllocatedToEmployeeID = @empId
AND NOT EXISTS (SELECT FogBugzLinkID FROM FogBugzAttachment)
AND (SELECT MAX(TimeStamp) 
 FROM SupportTicketData
 WHERE SupportTickets.SupportTicketID = SupportTicketData.SupportTicketID) < @warningDt
UNION
SELECT SupportTickets.* FROM SupportTickets
JOIN SupportTicketData ON SupportTickets.SupportTicketID = SupportTicketData.SupportTicketID
WHERE SupportTickets.StatusID != 3
AND SupportTickets.AllocatedToEmployeeID = @empId
AND SupportTicketData.TimeStamp = (SELECT MAX(TimeStamp) FROM SupportTicketData
                   WHERE SupportTickets.SupportTicketID = SupportTicketData.SupportTicketID)
AND SupportTicketData.RaisedByUser = 1
UNION
SELECT * FROM SupportTickets
WHERE StatusID != 3
AND SupportTickets.IsEscalated = 1

【问题讨论】:

  • 不要在 LINQ 中优化。编写一个 SProc 并调用它。
  • 性能会有这么大的提升吗?
  • Ors (||) 对性能没有好处。最好稍后分解查询并合并结果。我和@LIUFA 在一起,因为这是构建的,我将使用数据库来执行此操作,最有可能存储 proc 和 temp 表。
  • 啊,好吧,我会尝试一个存储过程并导入到我的 .edmx 文件中。

标签: c# sql linq entity-framework linq-to-entities


【解决方案1】:

因此,使用像我最初语句中的存储过程似乎比使用可怕的 LINQ OR 语句更有效。

我会将此标记为答案,以便将其关闭。看看我对 SPROC 的原始问题。

【讨论】:

    猜你喜欢
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    相关资源
    最近更新 更多