简体   繁体   中英

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. 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.

Both tables have indexes on the id. The id is not the primary key, obviously.

I am not sure if what I am doing is the most performant way of setting up this select. Is it better to have those individual selects combined in one 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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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