Gần đây tôi đã nâng cấp lên VS 2010 và đang chơi với LINQ cho Dataset. Tôi có một tập dữ liệu được đánh máy mạnh cho Ủy quyền nằm trong HttpCache của Ứng dụng web ASP.NET.
Vì vậy, tôi muốn biết đâu là cách nhanh nhất để kiểm tra xem người dùng có được phép làm điều gì đó hay không. Đây là mô hình dữ liệu của tôi và một số thông tin khác nếu ai đó quan tâm.
Tôi đã kiểm tra 3 cách:
- cơ sở dữ liệu trực tiếp
- Truy vấn LINQ với điều kiện Where là "Tham gia" - Cú pháp
- Truy vấn LINQ với Tham gia - Cú pháp
Đây là kết quả với 1000 lệnh gọi trên mỗi hàm:
1. kiểm tra:
- 4,2841519 giây.
- 115,7796925 giây.
- 2,024749 giây.
2. đánh giá:
- 3.1954857 giây
- 84,97047 giây.
- 1,5783397 giây.
3. tùy chọn:
- 2.7922143 giây.
- 97,8713267 giây.
- 1,8432163 giây.
Trung bình cộng:
- Cơ sở dữ liệu: 3,4239506333 giây.
- Trong đó: 99,5404964 giây.
- Tham gia: 1,815435 giây.
Tại sao phiên bản Tham gia nhanh hơn rất nhiều so với cú pháp where khiến nó trở nên vô dụng mặc dù là một người mới LINQ, nó có vẻ là dễ đọc nhất. Hay tôi đã bỏ lỡ điều gì đó trong truy vấn của mình?
Đây là các truy vấn LINQ, tôi bỏ qua cơ sở dữ liệu:
Ở đâu :
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
Tham gia:
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
Cảm ơn bạn trước.
Chỉnh sửa : sau một số cải tiến trên cả hai truy vấn để nhận được các giá trị hiệu suất có ý nghĩa hơn, lợi thế của JOIN thậm chí còn lớn hơn nhiều lần so với trước đây:
Tham gia :
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
Ở đâu :
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
Kết quả cho 1000 cuộc gọi (trên máy tính nhanh hơn)
- Tham gia | 2. Ở đâu
1. kiểm tra:
- 0,0713669 giây.
- 12,7395299 giây.
2. đánh giá:
- 0,0492458 giây.
- 12,3885925 giây.
3. tùy chọn:
- 0,0501982 giây.
- 13,3474216 giây.
Trung bình cộng:
- Tham gia: 0,0569367 giây.
- Trong đó: 12,8251813 giây.
Tham gia nhanh hơn 225 lần
Kết luận: tránh WHERE để chỉ định quan hệ và sử dụng JOIN bất cứ khi nào có thể (chắc chắn trong LINQ đến DataSet và Linq-To-Objects
nói chung).
Join
gì, tại sao phải dựa vào trình tối ưu hóa nếu bạn có thể viết mã tối ưu hóa ngay từ đầu? Nó cũng làm cho ý định của bạn rõ ràng hơn. Vì vậy, những lý do tương tự tại sao bạn nên thích THAM GIA trong sql .