猿问

为什么LINQ连接比链接到哪里要快得多?

为什么LINQ连接比链接到哪里要快得多?

我最近升级到VS 2010,并正在玩LINQtoDataSet。我有一个强类型的授权数据集,它位于ASP.NETWebApplication的HttpCache中。

所以我想知道什么是检查用户是否被授权做某事的最快方法。这里如果有人感兴趣的话我的数据模型和其他信息。

我检查了三种方法:

  1. 直接

    数据库

  2. Linq查询

    哪里

    作为“联接”的条件-句法
  3. Linq查询

    加入

    -句法

以下是对每个函数进行1000次调用的结果:

1.国际:

  1. 4,2841519秒
  2. 115,7796925秒
  3. 2,024749秒

2.国际:

  1. 3,1954857秒
  2. 84,97047秒
  3. 1,5783397秒

3.国际:

  1. 2,7922143秒
  2. 97,8713267秒
  3. 1,8432163秒

平均:

  1. 数据库:3,4239506333秒
  2. 地点:99,5404964秒
  3. 加入:1,815435秒。

为什么连接版本比WHERE语法快得多,这使得它变得无用,尽管作为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.AnyEnd Function

加入:

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 _

提前谢谢

绝地无双
浏览 248回答 3
3回答

临摹微笑

您的第一种方法(DB中的SQL查询)非常有效,因为DB知道如何执行联接。但是,将其与其他方法进行比较是没有意义的,因为它们直接在内存中工作(Linq To DataSet)具有多个表和Where条件实际上执行笛卡尔积在所有的桌子中,然后过滤满足条件的行。这意味着Where为每个行组合(N1*n2*n3*n4)评估条件。这个Join运算符从第一个表中获取行,然后只从第二个表中获取具有匹配键的行,然后只从第三个表获取具有匹配键的行,依此类推。这要高效得多,因为它不需要执行那么多的操作

叮当猫咪

这个Join因为该方法知道如何组合表以将结果降为相关的组合,因此速度要快得多。当你使用Where要指定关系,必须创建每个可能的组合,然后测试条件以确定哪些组合是相关的。这个Join方法可以设置哈希表,将其用作快速将两个表压缩到一起的索引,而Where方法在已经创建了所有组合之后运行,因此它不能使用任何技巧来预先减少组合。

开心每一天1111

您真正需要知道的是为这两个语句创建的SQL。有几种方法可以实现它,但最简单的方法是使用LinqPad。查询结果上方有几个按钮将更改为SQL。这会给你更多的信息。不过,你在那里分享了很棒的信息。
随时随地看视频慕课网APP
我要回答