简体   繁体   English

单独的 LINQ2SQL 选择在两个索引表上的组和连接与一个组合 select 的性能

[英]Performance of separate LINQ2SQL selects with group and join on two indexed tables vs. one combined select

I need to retrieve records from a table (tab_activities), grouped by ID, only the latest record of each group determined by date.我需要从按 ID 分组的表 (tab_activities) 中检索记录,只有按日期确定的每个组的最新记录。 Of those latest records I only need those with a specific property (finished) not yet set.在这些最新记录中,我只需要那些尚未设置特定属性(已完成)的记录。 In the end i have to crosscheck if any activities are also registered in a blacklist (tab_flaggedActivities) and then do something with all activities not finished and not flagged.最后,我必须交叉检查是否有任何活动也注册在黑名单(tab_flaggedActivities)中,然后对所有未完成且未标记的活动进行操作。

Both tables have indexes on the id.两个表都有关于 id 的索引。 The id is not the primary key, obviously.显然,id 不是主键。

I am not sure if what I am doing is the most performant way of setting up this select.我不确定我正在做的是否是设置此 select 的最高效方式。 Is it better to have those individual selects combined in one select?将这些单独的选择组合在一个 select 中会更好吗? If yes, how would I do that?如果是,我会怎么做?

// Retrieve only the latest activity entry of each known activity-ID
var latestActivityRecords = from activity in dc.tab_activities
                            where activity.dateRegistered > DateTime.Now.AddDays(-MaxAge)
                            group activity by activity.id
                            into groups
                            select groups.OrderByDescending(p => p.dateRegistered).First();

// Filter activities that are not finished
var unfinishedActivityRecords = from activity in latestActivityRecords
                                where !activity.finished
                                select activity;

// Check if any of those are in blacklist (different table)
var flaggedActivityRecords = from activity in unfinishedActivityRecords
                             join flaggedActivity in dc.tab_flaggedActivities 
                             on activity.id equals flaggedActivity.id
                             select activity;

if (unfinishedActivities != null)
{
    // Do something with all unfinished / unflagged activities 
    foreach (var activityRecord in unfinishedActivityRecords)
    {
        if (!flaggedActivityRecords.Any(p => p.id == activityRecord.id))
        {
            DoSomething(activityRecord);
        }
    }
}

If what you meant was combining the if Any test with the queries, you can reverse the meaning of the last query and just loop over the result, executing the filtering on the database server:如果您的意思是将if Any测试与查询结合起来,您可以反转最后一个查询的含义并循环遍历结果,在数据库服务器上执行过滤:

var unflaggedActivityRecords = from activity in unfinishedActivityRecords
                               where !dc.tab_flaggedActivities.Select(fa => fa.id).Contains(activity.id)
                               select activity;

if (unfinishedActivities != null) {
    // Do something with all unfinished / unflagged activities 
    foreach (var activityRecord in unflaggedActivityRecords) {
        DoSomething(activityRecord);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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