C# 如果没有要返回的结果集,查询似乎非常慢

C# 如果没有要返回的结果集,查询似乎非常慢,c#,sql,linq,C#,Sql,Linq,我正在一个web项目中使用LINQtoSQL。我从linq查询中得到了下面的sql,它在除not exists子查询返回空之外的任何情况下都能正常工作 选择[t1].[Name]作为[CategoryName],[t1].[CategoryID]作为[CategoryID] 从[Store].[CategoryCountryCategoryTypeMappings]到[t0] [t0].[CategoryID]=[t1].[CategoryID]上的[t1]内部联接[Store].[Catego

我正在一个web项目中使用LINQtoSQL。我从linq查询中得到了下面的sql,它在除not exists子查询返回空之外的任何情况下都能正常工作

选择[t1].[Name]作为[CategoryName],[t1].[CategoryID]作为[CategoryID] 从[Store].[CategoryCountryCategoryTypeMappings]到[t0] [t0].[CategoryID]=[t1].[CategoryID]上的[t1]内部联接[Store].[Categories]作为[t1] 其中[t1].[StorefrontID]=73且不存在 选择NULL作为[空] 从[dbo].[DownloadLog]作为[t2] 其中[t2].[CategoryCountryCategoryTypeMappingID]=[t0].[CategoryCountryCategoryTypeMappingID]和DATEPARTHour[t2].[DTS]=11和CONVERTDATE[t2].[DTS]=CONVERTDATE,GETDATE 按[t1].[Name],[t1].[CategoryID]分组 linq如下所示:

var notDLToUnion = (from ntdl in notDownloadedIds
                    join cat in cDataContext.Categories
                    on ntdl.CategoryID equals cat.CategoryID
                    where cat.StorefrontID == StorefrontID
                    group ntdl by new { cat.Name, cat.CategoryID } into t1
                    select new CategoryStruct { CategoryName = t1.Key.Name, Status = 0, AverageResponseTime = 0, categoryId = t1.Key.CategoryID });
 var notDLToUnion =  (from final in
                                (from ntdl in notDownloadedIds
                                join cat in cDataContext.Categories
                                on ntdl.CategoryID equals cat.CategoryID
                                where cat.StorefrontID == StorefrontID
                                select new {ntdl,cat})
                            group final by new {final.cat.CategoryID} into t1
                            orderby t1.Key.CategoryID
                            select new CategoryStruct { CategoryName = t1.Max(x=>x.cat.Name), Status = 0, AverageResponseTime = 0, categoryId = t1.Key.CategoryID }
                            );
如果notdownloadedds是一个空集,我可以做些什么来重新调整我的linqor sql,使其运行得同样快

另一个途径是,我真的不需要按cat.name和cat.categoryId分组。。。我只需要按cat.Name进行分组,但我需要访问cat.id,并且两者之间存在一对一的关系

补充说明:一些实验发现了一些更为有趣的结果。删除group by使其快速,删除group by key使其快速,删除Not existswith或Not empty set下的子查询使其快速。当子查询有行时,其速度将加快

这当然不是很快,而且也不是很快,如果我在分组之后将categoryName内部加入CategoryID

编辑:添加下载ID

 notDownloadedIds = cDataContext.CategoryCountryCategoryTypeMappings.Where(mapping =>!
currentLogs.Select(dll => dll.CategoryCountryCategoryTypeMappingID)
.Any(id => id ==mapping.CategoryCountryCategoryTypeMappingID));

我将删除子查询,并使其成为左外部联接,如下所示

SELECT [t1].[Name] AS [CategoryName], [t1].[CategoryID] AS [categoryId]
FROM [Store].[CategoryCountryCategoryTypeMappings] AS [t0]
INNER JOIN [Store].[Categories] AS [t1] ON [t0].[CategoryID] = [t1].[CategoryID]
LEFT OUTER JOIN [dbo].[DownloadLog] AS [t2] 
    ON [t2].[CategoryCountryCategoryTypeMappingID] = [t0].[CategoryCountryCategoryTypeMappingID]) 
WHERE ([t1].[StorefrontID] = 73) 
    AND [t2].[CategoryCountryCategoryTypeMappingID] IS NULL
    AND (DATEPART(Hour, [t2].[DTS]) = 11) 
    AND (CONVERT(DATE, [t2].[DTS]) = CONVERT(DATE,GETDATE())
GROUP BY [t1].[Name], [t1].[CategoryID]

这是我头脑中建立的,未经测试,但我相信它会为您获得相同的结果集,并且可能会更快。

我仍然不确定sql到底发生了什么,但我最终以更好的方式使用了linq。当你发表linq声明时

 (from f in foo
 join b in bar
 on b.id equals f.id
 select f)
它没有像我所相信的那样选择f和b之间的连接。它只选择f,必须选择新的{f,b}才能同时获得这两个

我对linq的修复结果如下:

var notDLToUnion = (from ntdl in notDownloadedIds
                    join cat in cDataContext.Categories
                    on ntdl.CategoryID equals cat.CategoryID
                    where cat.StorefrontID == StorefrontID
                    group ntdl by new { cat.Name, cat.CategoryID } into t1
                    select new CategoryStruct { CategoryName = t1.Key.Name, Status = 0, AverageResponseTime = 0, categoryId = t1.Key.CategoryID });
 var notDLToUnion =  (from final in
                                (from ntdl in notDownloadedIds
                                join cat in cDataContext.Categories
                                on ntdl.CategoryID equals cat.CategoryID
                                where cat.StorefrontID == StorefrontID
                                select new {ntdl,cat})
                            group final by new {final.cat.CategoryID} into t1
                            orderby t1.Key.CategoryID
                            select new CategoryStruct { CategoryName = t1.Max(x=>x.cat.Name), Status = 0, AverageResponseTime = 0, categoryId = t1.Key.CategoryID }
                            );

此外,如果有人想建议进行清理,使其更具可读性,我将非常愿意接受

这听起来更像是Sql性能问题,而不是实际的LINQ问题。我建议您首先尝试使用ManagementStudio的性能工具分析查询。一旦它像普通SQL一样顺利运行,那么它应该和LINQ一样好。我同意,我从SQL方面开始,然后返回。但我想我会尽可能多地提供信息。你怎么能不下载EDID呢?推断的SQL代码中有一些元素与您的LINQ查询不匹配,例如,所有与日期有关的条件。@polkduran添加了NotDownloadEds您将三个查询堆叠在彼此的currentLogs、NotDownloadEds和notDLToUnion之上。很可能存储其中一个查询的中间结果会更快。此查询总是返回一个空集,我会考虑对其进行编辑