如果没有返回结果集,查询似乎真的很慢

时间:2014-02-18 16:36:04

标签: c# sql linq

我在web项目中使用linq to sql。我从linq查询得到了下面的sql并且它在任何情况下运行良好除了不存在子查询返回空

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]
WHERE ([t1].[StorefrontID] = 73) AND (NOT (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[DownloadLog] AS [t2]
    WHERE ([t2].[CategoryCountryCategoryTypeMappingID] = [t0].[CategoryCountryCategoryTypeMappingID]) AND (DATEPART(Hour, [t2].[DTS]) = 11) AND (CONVERT(DATE, [t2].[DTS]) = CONVERT(DATE,GETDATE()))
    )))
GROUP BY [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 });

如果notDownloadedIds是空集,我该怎么做才能重新调整我的linq(或sql)运行速度呢?

另一个途径,我真的不需要按cat.name和cat.categoryId分组...我只需要按cat.Name分组,但我需要访问cat.id,并且有一个到两者之间的一种关系。

添加评论:一些经验已经发现了一些奇怪的结果。通过删除组使其快速,按键删除一个组使其快速,删除不存在(有或没有空集)下的子查询使其快速。当子查询有行时,它很快。

它当然不是那么快,而且如果我将groupName加到groupID之后的CategoryID,它也不会很快。

编辑:添加downloadIds

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

2 个答案:

答案 0 :(得分:1)

我将删除子查询并将其设为LEFT OUTER JOIN,如此

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]

这是建立在我的头顶并且未经测试但我相信它应该为你提供相同的结果集,并且可能更快。

答案 1 :(得分:0)

我仍然不确定sql会发生什么,但我最终以更好的方式使用linq。当你做一个linq语句

 (from f in foo
 join b in bar
 on b.id equals f.id
 select f)

它没有选择f和b之间的连接,就像我所认为的那样。它只选择f,一个必须select new {f,b}才能同时获得。

我对我的linq的修复最终看起来像这样:

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

如果有人想建议清理以使其更具可读性,我也非常愿意接受。