Я недавно обновился до VS 2010 и играю с LINQ to Dataset. У меня есть строго типизированный набор данных для авторизации, который находится в HttpCache веб-приложения ASP.NET.
Итак, я хотел знать, что на самом деле является самым быстрым способом проверить, авторизован ли пользователь на что-либо. Здесь - моя модель данных и некоторые другие сведения, если кому-то это интересно.
Я проверил 3 способа:
- прямой база данных
- LINQ-запрос с , где означает «Join» - синтаксис
- LINQ-запрос с Присоединение - Синтаксис
Это результаты с 1000 вызовами для каждой функции:
1.Iteration:
- 4,2841519 с.
- 115,7796925 с.
- 2,024749 сек.
2.Iteration:
- 3,1954857 сек.
- 84,97047 сек.
- 1,5783397 сек.
3.Iteration:
- 2,7922143 с.
- 97,8713267 сек.
- 1,8432163 сек.
Средний
- База данных: 3,4239506333 сек.
- Где: 99,5404964 сек.
- Регистрация: 1815435 сек.
Почему Join-версия намного быстрее, чем синтаксис 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.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
Заранее спасибо.
Редактировать : после некоторых улучшений в обоих запросах, чтобы получить более значимые значения perfomance, преимущество 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.Iteration:
- 0,0713669 сек.
- 12,7395299 сек.
2.Iteration:
- 0,0492458 сек.
- 12,3885925 сек.
3.Iteration:
- 0,0501982 сек.
- 13,3474216 сек.
Средний
- Регистрация: 0,0569367 сек.
- Где: 12,8251813 сек.
Регистрация в 225 раз быстрее
Вывод: избегайте ГДЕ указывать отношения и по возможности используйте JOIN (определенно в LINQ to DataSet и Linq-To-Objects
в целом).