Comparing performance of generated queries for Any() vs Count() in Entity Framework 5

怎甘沉沦 提交于 2020-01-14 14:24:31

问题


In my project I use Entity Framework 4.4.0.0 and I have the following dilemma. I have to check if an user is activated. My query looks like:

Any()

_context.Users.Any(u => u.Id == userId && u.IsActivated);

The generated sql is:

SELECT CASE
         WHEN ( EXISTS (SELECT 1 AS [C1]
                        FROM   [dbo].[Users] AS [Extent1]
                        WHERE  ( [Extent1].[Id] = @p__linq__0 )
                               AND ( [Extent1].[IsActivated] = 1 )) ) THEN cast(1 AS BIT)
         WHEN ( NOT EXISTS (SELECT 1 AS [C1]
                            FROM   [dbo].[Users] AS [Extent2]
                            WHERE  ( [Extent2].[Id] = @p__linq__0 )
                                AND ( [Extent2].[IsActivated] = 1 )) ) THEN cast(0 AS BIT)
       END AS [C1]
FROM   (SELECT 1 AS X) AS [SingleRowTable1] 

For Count() I get this query:

SELECT [GroupBy1].[A1] AS [C1]
FROM   (SELECT COUNT(1) AS [A1]
        FROM   [dbo].[Users] AS [Extent1]
        WHERE  ( [Extent1].[Id] = @p__linq__0 )
               AND ( [Extent1].[IsActivated] = 1 )) AS [GroupBy1] 

Does this looks right? I am not very good as sql ... but it looks not very efficient to me. Am I missing something?

Is 'select count(*) from dbo.Users where id=@id and IsActivated=1' less efficient?


回答1:


It depends.

The EXISTS implementation isn't that great either. It will perform the check twice if there are 0 rows. In that case the COUNT one will be better as it only has to search for the non existent row and count it once.

You may find that checking

_context.Users
        .Where(u => u.Id == userId && u.IsActivated)
        .Select(u=> true)
        .FirstOrDefault();

gives a better plan than both (amended following Luke's suggestion). Testing on EF4 the query generated is along the lines of

SELECT TOP (1) cast(1 AS BIT) AS [C1]
FROM   Users
WHERE  userId = @userId
       AND IsActivated = 1 

Meaning it doesn't process unnecessary additional rows if more than one exists and only performs the search for rows matching the WHERE once.




回答2:


Yes it is. When you perform a count you will select all the entries that match your clause and count then. Using Any() your query will return at a first sign of a registry that match the clause. I'm my opnion it's always better to use Any() than count(), except when you really need that number



来源:https://stackoverflow.com/questions/17890645/comparing-performance-of-generated-queries-for-any-vs-count-in-entity-framew

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!