¿Por qué LINQ JOIN es mucho más rápido que vincular con WHERE?

Recientemente me actualicé a VS 2010 y estoy jugando con LINQ to Dataset. Tengo un conjunto de datos con tipo fuerte para Autorización que se encuentra en HttpCache de una aplicación web ASP.NET.

Así que quería saber cuál es la forma más rápida de verificar si un usuario está autorizado a hacer algo. @Aqu es mi modelo de datos y alguna otra información si alguien está interesado.

He comprobado 3 formas:

directbase de datoonsulta @LINQ conDónd condiciones como "Unirse" - Sintaxisonsulta @LINQ conUnirs - Sintaxis

Estos son los resultados con 1000 llamadas en cada función:

1.Interación:

4,2841519 seg. 115,7796925 seg. 2,024749 seg.

2.Interación:

3,1954857 seg. 84,97047 seg. 1,5783397 seg.

3.Interación:

2,7922143 seg. 97,8713267 seg. 1,8432163 seg.

Promedio

Database: 3,4239506333 seg.Where: 99,5404964 sec.Join: 1,815435 seg.

Why es la versión Join mucho más rápida que la sintaxis where, lo que la hace inútil, aunque como novato en LINQ parece ser la más legible. ¿O me he perdido algo en mis consultas?

Aquí están las consultas LINQ, me salto la base de datos:

Dónd:

Public Function hasAccessDS_Where(ByVal accessRule As String) As Boolean
    Dim userID As Guid = DirectCast(Membership.GetUser.ProviderUserKey, Guid)
    Dim query = From accRule In Authorization.dsAuth.aspnet_AccessRule, _
                roleAccRule In Authorization.dsAuth.aspnet_RoleAccessRule, _
                role In Authorization.dsAuth.aspnet_Roles, _
                userRole In Authorization.dsAuth.aspnet_UsersInRoles _
                Where accRule.idAccessRule = roleAccRule.fiAccessRule _
                And roleAccRule.fiRole = role.RoleId _
                And userRole.RoleId = role.RoleId _
                And userRole.UserId = userID And accRule.RuleName.Contains(accessRule)
                Select accRule.idAccessRule
    Return query.Any
End Function

Unirse

Public Function hasAccessDS_Join(ByVal accessRule As String) As Boolean
    Dim userID As Guid = DirectCast(Membership.GetUser.ProviderUserKey, Guid)
    Dim query = From accRule In Authorization.dsAuth.aspnet_AccessRule _
                Join roleAccRule In Authorization.dsAuth.aspnet_RoleAccessRule _
                On accRule.idAccessRule Equals roleAccRule.fiAccessRule _
                Join role In Authorization.dsAuth.aspnet_Roles _
                On role.RoleId Equals roleAccRule.fiRole _
                Join userRole In Authorization.dsAuth.aspnet_UsersInRoles _
                On userRole.RoleId Equals role.RoleId _
                Where userRole.UserId = userID And accRule.RuleName.Contains(accessRule)
                Select accRule.idAccessRule
    Return query.Any
End Function

Gracias de antemano

Edita: después de algunas mejoras en ambas consultas para obtener valores de rendimiento más significativos, la ventaja de JOIN es incluso muchas veces mayor que antes:

Unirs:

Public Overloads Shared Function hasAccessDS_Join(ByVal userID As Guid, ByVal idAccessRule As Int32) As Boolean
    Dim query = From accRule In Authorization.dsAuth.aspnet_AccessRule _
                   Join roleAccRule In Authorization.dsAuth.aspnet_RoleAccessRule _
                   On accRule.idAccessRule Equals roleAccRule.fiAccessRule _
                   Join role In Authorization.dsAuth.aspnet_Roles _
                   On role.RoleId Equals roleAccRule.fiRole _
                   Join userRole In Authorization.dsAuth.aspnet_UsersInRoles _
                   On userRole.RoleId Equals role.RoleId _
                   Where accRule.idAccessRule = idAccessRule And userRole.UserId = userID
             Select role.RoleId
    Return query.Any
End Function

Dónd:

Public Overloads Shared Function hasAccessDS_Where(ByVal userID As Guid, ByVal idAccessRule As Int32) As Boolean
    Dim query = From accRule In Authorization.dsAuth.aspnet_AccessRule, _
           roleAccRule In Authorization.dsAuth.aspnet_RoleAccessRule, _
           role In Authorization.dsAuth.aspnet_Roles, _
           userRole In Authorization.dsAuth.aspnet_UsersInRoles _
           Where accRule.idAccessRule = roleAccRule.fiAccessRule _
           And roleAccRule.fiRole = role.RoleId _
           And userRole.RoleId = role.RoleId _
           And accRule.idAccessRule = idAccessRule And userRole.UserId = userID
           Select role.RoleId
    Return query.Any
End Function
Resultado por 1000 llamadas (en una computadora más rápida)Join | 2. Donde

1.Interación:

0,0713669 seg. 12,7395299 seg.

2.Interación:

0,0492458 seg. 12,3885925 seg.

3.Interación:

0,0501982 seg. 13,3474216 seg.

Promedio

Join: 0,0569367 sec.Dónde: 12,8251813 seg.

Join es 225 veces más rápido

Conclusión evite DONDE especificar relaciones y use UNIRSE siempre que sea posible (definitivamente enLINQ to DataSet yLinq-To-Objects en general)

Respuestas a la pregunta(3)

Su respuesta a la pregunta