Tim*_*ter 96 .net linq performance join linq-to-dataset
我最近升级到了VS 2010,正在玩LINQ to Dataset.我有一个强大的类型化的Authorization数据集,它位于ASP.NET WebApplication的HttpCache中.
所以我想知道实际上检查用户是否有权做某事的最快方法.如果有人感兴趣的话,这是我的数据模型和其他一些信息.
我检查了3种方法:
这些是每个函数1000次调用的结果:
1.Iteration:
2.Iteration:
3.Iteration:
平均:
为什么Join-version比where-syntax快得多,这使得它无用尽管作为LINQ新手它似乎是最清晰的.或者我在查询中遗漏了什么?
这是LINQ查询,我跳过数据库:
地点:
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
Run Code Online (Sandbox Code Playgroud)
加入:
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
Run Code Online (Sandbox Code Playgroud)
先感谢您.
编辑:在对两个查询进行一些改进以获得更有意义的性能值之后,JOIN的优势甚至比之前大很多倍:
加入:
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
Run Code Online (Sandbox Code Playgroud)
地点:
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
Run Code Online (Sandbox Code Playgroud)
1.Iteration:
2.Iteration:
3.Iteration:
平均:
加入速度提高了225倍
结论:避免在指定的关系,并使用JOIN尽可能(肯定是在LINQ到数据集和Linq-To-Objects一般).
Tho*_*que 75
您的第一种方法(DB中的SQL查询)非常有效,因为DB知道如何执行连接.但是将它与其他方法进行比较并没有多大意义,因为它们直接在内存中工作(Linq to DataSet)
具有多个表和Where条件的查询实际上执行所有表的笛卡尔积,然后过滤满足条件的行.这意味着Where为每个行组合评估条件(n1*n2*n3*n4)
在Join操作者需要从所述第一表中的行,然后与从第二表中的匹配项,则仅利用从所述第三表中的匹配键的行中,等等只需要的行.这样效率更高,因为它不需要执行许多操作
Guf*_*ffa 19
的Join要快得多,因为方法知道如何将表结合起来,以减少结果的相关组合.当您用于Where指定关系时,它必须创建每个可能的组合,然后测试条件以查看哪些组合是相关的.
该Join方法可以设置哈希表以用作快速压缩两个表的索引,而该Where方法在已经创建所有组合之后运行,因此它不能使用任何技巧来预先减少组合.
你真正需要知道的是为这两个语句创建的sql.有几种方法可以实现,但最简单的方法是使用LinqPad.查询结果正上方有几个按钮将更改为sql.这将为您提供比其他任何东西更多的信息.
你分享的很棒的信息.
| 归档时间: |
|
| 查看次数: |
20376 次 |
| 最近记录: |