私は最近 VS 2010 にアップグレードし、LINQ to Dataset で遊んでいます。ASP.NET WebApplication の HttpCache にある Authorization 用の厳密に型指定されたデータセットがあります。
だから私は、ユーザーが何かをする権限があるかどうかを実際に確認する最も速い方法は何かを知りたいと思っていました. これが私のデータモデルと、誰かが興味を持っている場合のその他の情報です。
私は3つの方法をチェックしました:
- 直接データベース
- Where条件を「結合」として使用する LINQ クエリ- 構文
- Joinを使用した LINQ クエリ- 構文
これらは、各関数で 1000 回の呼び出しを行った結果です。
1.反復:
- 4,2841519秒
- 115,7796925秒
- 2,024749秒
2.反復:
- 3,1954857秒
- 84,97047秒
- 1,5783397秒
3.反復:
- 2,7922143秒
- 97,8713267秒
- 1,8432163秒
平均:
- データベース: 3,4239506333 秒
- 場所: 99,5404964 秒。
- 結合: 1,815435 秒。
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
加入:
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
前もって感謝します。
編集:より意味のあるパフォーマンス値を取得するために両方のクエリをいくつか改善した後、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
どこで:
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
1000 回の呼び出しの結果 (より高速なコンピューターで)
- 参加 | 2.どこで
1.反復:
- 0,0713669秒
- 12,7395299秒
2.反復:
- 0,0492458秒
- 12,3885925秒
3.反復:
- 0,0501982秒
- 13,3474216秒
平均:
- 結合: 0,0569367 秒。
- ここで: 12,8251813 秒。
Join は 225 倍高速です
結論: WHERE を使用してリレーションを指定することは避け、可能な限り JOIN を使用します ( LINQ to DataSetおよびLinq-To-Objects
一般的には間違いなく)。