최근에 VS 2010으로 업그레이드했고 LINQ to Dataset을 가지고 놀았습니다. ASP.NET WebApplication의 HttpCache에있는 권한 부여를위한 강력한 형식의 데이터 집합이 있습니다.
그래서 저는 사용자가 무언가를 할 권한이 있는지 확인하는 가장 빠른 방법이 무엇인지 알고 싶었습니다. 누군가가 관심이 있다면 여기 내 데이터 모델과 다른 정보가 있습니다.
세 가지 방법을 확인했습니다.
- 직접 데이터베이스
- Where 조건이 "Join"인 LINQ 쿼리 -구문
- 조인을 사용한 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 초
- Where : 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 초
- Where : 12,8251813 초
가입 속도가 225 배 빠릅니다.
결론 : 관계를 지정하기 위해 WHERE를 피하고 가능할 때마다 JOIN을 사용하십시오 (확실히 LINQ to DataSet 및 Linq-To-Objects
일반적으로).
Join
. 왜 처음부터 최적화 된 코드를 작성할 수 있다면 최적화 프로그램에 의존합니까? 그것은 또한 당신의 의도를 더 명확하게합니다. 따라서 sql에서 JOIN을 선호해야하는 동일한 이유가 있습니다 .