Saya baru saja meningkatkan ke VS 2010 dan bermain-main dengan LINQ ke Dataset. Saya memiliki set data yang diketik kuat untuk Otorisasi yang ada di HttpCache dari ASP.NET WebApplication.
Jadi saya ingin tahu apa sebenarnya cara tercepat untuk memeriksa apakah pengguna berwenang untuk melakukan sesuatu. Berikut adalah model data saya dan beberapa informasi lain jika ada yang tertarik.
Saya telah memeriksa 3 cara:
- database langsung
- Query LINQ dengan kondisi Where sebagai "Join" - Syntax
- Kueri LINQ dengan Gabung - Sintaks
Ini adalah hasil dengan 1000 panggilan di setiap fungsi:
1. Iterasi:
- 4,2841519 dtk.
- 115,7796925 dtk.
- 2.024749 dtk.
2. Iterasi:
- 3,1954857 dtk.
- 84.97047 dtk.
- 1.5783397 dtk.
3. Iterasi:
- 2,7922143 dtk.
- 97,8713267 dtk.
- 1,8432163 dtk.
Rata-rata:
- Database: 3.4239506333 dtk.
- Dimana: 99,5404964 dtk.
- Bergabung: 1,815435 dtk.
Mengapa versi Gabung jauh lebih cepat daripada sintaks di mana yang membuatnya tidak berguna meskipun sebagai pemula LINQ tampaknya yang paling terbaca. Atau apakah saya melewatkan sesuatu dalam pertanyaan saya?
Berikut adalah kueri LINQ, saya melewatkan database:
Dimana :
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
Ikuti:
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
Terima kasih sebelumnya.
Sunting : setelah beberapa perbaikan pada kedua kueri untuk mendapatkan nilai kinerja yang lebih bermakna, keuntungan dari JOIN bahkan jauh lebih besar dari sebelumnya:
Gabung :
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
Dimana :
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
Hasil untuk 1000 panggilan (di komputer yang lebih cepat)
- Gabung | 2. Dimana
1. Iterasi:
- 0,0713669 dtk.
- 12.7395299 dtk.
2. Iterasi:
- 0,0492458 dtk.
- 12,3885925 dtk.
3. Iterasi:
- 0,0501982 dtk.
- 13.3474216 dtk.
Rata-rata:
- Bergabung: 0,0569367 dtk.
- Dimana: 12,8251813 dtk.
Bergabung 225 kali lebih cepat
Kesimpulan: hindari WHERE untuk menentukan relasi dan gunakan JOIN bila memungkinkan (pasti di LINQ ke DataSet dan Linq-To-Objects
secara umum).
Join
anywhy, mengapa mengandalkan pengoptimal jika Anda dapat menulis kode opimasi dari awal? Itu juga membuat niat Anda lebih jelas. Jadi alasan yang sama mengapa Anda harus lebih memilih GABUNG di sql .