[英]Cleaning a big sql query generated by the Entity Framework
我正在檢查我的SQL查詢以查看是否可以對其進行優化,然后發現了一個龐大的查詢,其中僅包含很少的邏輯。
我了解查詢的某些部分,但不確定為什么每次都會選擇這么多列。
為什么實體框架這么多地分配/選擇網站實體? (網站實體包含諸如ID,標題,描述之類的列)。
FROM (SELECT
[Project4].[Id] AS [Id],
[Project4].[Title] AS [Title],
[Project4].[Description] AS [Description],
[Project4].[Url] AS [Url],
[Project4].[BannerURL] AS [BannerURL],
[Project4].[UserID] AS [UserID],
[Project4].[CategoryID] AS [CategoryID],
[Project4].[Keywords] AS [Keywords],
[Project4].[Enabled] AS [Enabled],
[Project4].[DateAdded] AS [DateAdded],
[Project4].[Sponsored] AS [Sponsored],
[Project4].[ServerIP] AS [ServerIP],
[Project4].[ServerPort] AS [ServerPort],
[Project4].[MonitorCheckedDate] AS [MonitorCheckedDate],
[Project4].[IsOnline] AS [IsOnline],
[Project4].[BannerFileName] AS [BannerFileName],
[Project4].[Thumbnail] AS [Thumbnail],
[Project4].[C1] AS [C1],
[Project4].[C2] AS [C2],
完整的SQL查詢:
SELECT TOP (25)
[Filter8].[Id1] AS [Id],
[Filter8].[Title] AS [Title],
[Filter8].[Description] AS [Description],
[Filter8].[Url] AS [Url],
[Filter8].[BannerURL] AS [BannerURL],
[Filter8].[UserID] AS [UserID],
[Filter8].[CategoryID] AS [CategoryID],
[Filter8].[Keywords] AS [Keywords],
[Filter8].[Enabled] AS [Enabled],
[Filter8].[DateAdded] AS [DateAdded],
[Filter8].[Sponsored] AS [Sponsored],
[Filter8].[ServerIP] AS [ServerIP],
[Filter8].[ServerPort] AS [ServerPort],
[Filter8].[MonitorCheckedDate] AS [MonitorCheckedDate],
[Filter8].[IsOnline] AS [IsOnline],
[Filter8].[BannerFileName] AS [BannerFileName],
[Filter8].[Thumbnail] AS [Thumbnail]
// What's going on here?
FROM ( SELECT [Filter7].[Id1], [Filter7].[Title], [Filter7].[Description], [Filter7].[Url], [Filter7].[BannerURL], [Filter7].[UserID], [Filter7].[CategoryID], [Filter7].[Keywords], [Filter7].[Enabled], [Filter7].[DateAdded], [Filter7].[Sponsored], [Filter7].[ServerIP], [Filter7].[ServerPort], [Filter7].[MonitorCheckedDate], [Filter7].[IsOnline], [Filter7].[BannerFileName], [Filter7].[Thumbnail], [Filter7].[C1], [Filter7].[C2], [Filter7].[C3], [Filter7].[IsAdminVerified1], [Filter7].[IsEmailVerified1], [Filter7].[BannedEndDate1], [Filter7].[BannedEndDate2], row_number() OVER (ORDER BY [Filter7].[Sponsored] DESC, [Filter7].[C2] DESC, [Filter7].[C3] DESC, [Filter7].[C1] DESC, [Filter7].[DateAdded] DESC) AS [row_number]
FROM ( SELECT [Filter6].[Id1], [Filter6].[Title], [Filter6].[Description], [Filter6].[Url], [Filter6].[BannerURL], [Filter6].[UserID], [Filter6].[CategoryID], [Filter6].[Keywords], [Filter6].[Enabled], [Filter6].[DateAdded], [Filter6].[Sponsored], [Filter6].[ServerIP], [Filter6].[ServerPort], [Filter6].[MonitorCheckedDate], [Filter6].[IsOnline], [Filter6].[BannerFileName], [Filter6].[Thumbnail], [Filter6].[C1], [Filter6].[C2], [Filter6].[C3], [Filter6].[IsAdminVerified1], [Filter6].[IsEmailVerified1], [Filter6].[BannedEndDate1], [Filter6].[BannedEndDate2]
FROM ( SELECT [Filter5].[Id1], [Filter5].[Title], [Filter5].[Description], [Filter5].[Url], [Filter5].[BannerURL], [Filter5].[UserID], [Filter5].[CategoryID], [Filter5].[Keywords], [Filter5].[Enabled], [Filter5].[DateAdded], [Filter5].[Sponsored], [Filter5].[ServerIP], [Filter5].[ServerPort], [Filter5].[MonitorCheckedDate], [Filter5].[IsOnline], [Filter5].[BannerFileName], [Filter5].[Thumbnail], [Filter5].[C1], [Filter5].[C2], [Filter5].[C3], [Filter5].[IsAdminVerified1], [Filter5].[IsEmailVerified1], [Filter5].[BannedEndDate1], [Filter5].[BannedEndDate2]
FROM ( SELECT [Project5].[Id] AS [Id1], [Project5].[Title] AS [Title], [Project5].[Description] AS [Description], [Project5].[Url] AS [Url], [Project5].[BannerURL] AS [BannerURL], [Project5].[UserID] AS [UserID], [Project5].[CategoryID] AS [CategoryID], [Project5].[Keywords] AS [Keywords], [Project5].[Enabled] AS [Enabled], [Project5].[DateAdded] AS [DateAdded], [Project5].[Sponsored] AS [Sponsored], [Project5].[ServerIP] AS [ServerIP], [Project5].[ServerPort] AS [ServerPort], [Project5].[MonitorCheckedDate] AS [MonitorCheckedDate], [Project5].[IsOnline] AS [IsOnline], [Project5].[BannerFileName] AS [BannerFileName], [Project5].[Thumbnail] AS [Thumbnail], [Project5].[C1] AS [C1], [Project5].[C2] AS [C2], [Project5].[C3] AS [C3], [Extent6].[IsAdminVerified] AS [IsAdminVerified1], [Extent7].[IsEmailVerified] AS [IsEmailVerified1], [Extent8].[BannedEndDate] AS [BannedEndDate1], [Extent9].[BannedEndDate] AS [BannedEndDate2]
// Why the repeat?
FROM (SELECT
[Project4].[Id] AS [Id],
[Project4].[Title] AS [Title],
[Project4].[Description] AS [Description],
[Project4].[Url] AS [Url],
[Project4].[BannerURL] AS [BannerURL],
[Project4].[UserID] AS [UserID],
[Project4].[CategoryID] AS [CategoryID],
[Project4].[Keywords] AS [Keywords],
[Project4].[Enabled] AS [Enabled],
[Project4].[DateAdded] AS [DateAdded],
[Project4].[Sponsored] AS [Sponsored],
[Project4].[ServerIP] AS [ServerIP],
[Project4].[ServerPort] AS [ServerPort],
[Project4].[MonitorCheckedDate] AS [MonitorCheckedDate],
[Project4].[IsOnline] AS [IsOnline],
[Project4].[BannerFileName] AS [BannerFileName],
[Project4].[Thumbnail] AS [Thumbnail],
[Project4].[C1] AS [C1],
[Project4].[C2] AS [C2],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[WebsiteOut] AS [Extent5]
WHERE ([Project4].[Id] = [Extent5].[WebsiteID]) AND ([Extent5].[Unique] = 1)) AS [C3]
FROM ( SELECT
[Project2].[Id] AS [Id],
[Project2].[Title] AS [Title],
[Project2].[Description] AS [Description],
[Project2].[Url] AS [Url],
[Project2].[BannerURL] AS [BannerURL],
[Project2].[UserID] AS [UserID],
[Project2].[CategoryID] AS [CategoryID],
[Project2].[Keywords] AS [Keywords],
[Project2].[Enabled] AS [Enabled],
[Project2].[DateAdded] AS [DateAdded],
[Project2].[Sponsored] AS [Sponsored],
[Project2].[ServerIP] AS [ServerIP],
[Project2].[ServerPort] AS [ServerPort],
[Project2].[MonitorCheckedDate] AS [MonitorCheckedDate],
[Project2].[IsOnline] AS [IsOnline],
[Project2].[BannerFileName] AS [BannerFileName],
[Project2].[Thumbnail] AS [Thumbnail],
CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[WebsiteRating] AS [Extent4]
WHERE [Project2].[Id] = [Extent4].[WebsiteID]
)) THEN CAST( [Project2].[C2] AS int) ELSE 5 END AS [C1],
[Project2].[C1] AS [C2]
FROM ( SELECT
[Project1].[Id] AS [Id],
[Project1].[Title] AS [Title],
[Project1].[Description] AS [Description],
[Project1].[Url] AS [Url],
[Project1].[BannerURL] AS [BannerURL],
[Project1].[UserID] AS [UserID],
[Project1].[CategoryID] AS [CategoryID],
[Project1].[Keywords] AS [Keywords],
[Project1].[Enabled] AS [Enabled],
[Project1].[DateAdded] AS [DateAdded],
[Project1].[Sponsored] AS [Sponsored],
[Project1].[ServerIP] AS [ServerIP],
[Project1].[ServerPort] AS [ServerPort],
[Project1].[MonitorCheckedDate] AS [MonitorCheckedDate],
[Project1].[IsOnline] AS [IsOnline],
[Project1].[BannerFileName] AS [BannerFileName],
[Project1].[Thumbnail] AS [Thumbnail],
[Project1].[C1] AS [C1],
(SELECT
AVG( CAST( [Extent3].[Rating] AS float)) AS [A1]
FROM [dbo].[WebsiteRating] AS [Extent3]
WHERE [Project1].[Id] = [Extent3].[WebsiteID]) AS [C2]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title],
[Extent1].[Description] AS [Description],
[Extent1].[Url] AS [Url],
[Extent1].[BannerURL] AS [BannerURL],
[Extent1].[UserID] AS [UserID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[Keywords] AS [Keywords],
[Extent1].[Enabled] AS [Enabled],
[Extent1].[DateAdded] AS [DateAdded],
[Extent1].[Sponsored] AS [Sponsored],
[Extent1].[ServerIP] AS [ServerIP],
[Extent1].[ServerPort] AS [ServerPort],
[Extent1].[MonitorCheckedDate] AS [MonitorCheckedDate],
[Extent1].[IsOnline] AS [IsOnline],
[Extent1].[BannerFileName] AS [BannerFileName],
[Extent1].[Thumbnail] AS [Thumbnail],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[WebsiteIn] AS [Extent2]
WHERE ([Extent1].[Id] = [Extent2].[WebsiteID]) AND ([Extent2].[Unique] = 1)) AS [C1]
FROM [dbo].[Websites] AS [Extent1]
) AS [Project1]
) AS [Project2]
) AS [Project4] ) AS [Project5]
INNER JOIN [dbo].[Users] AS [Extent6] ON [Project5].[UserID] = [Extent6].[Id]
INNER JOIN [dbo].[Users] AS [Extent7] ON [Project5].[UserID] = [Extent7].[Id]
LEFT OUTER JOIN [dbo].[Users] AS [Extent8] ON [Project5].[UserID] = [Extent8].[Id]
LEFT OUTER JOIN [dbo].[Users] AS [Extent9] ON [Project5].[UserID] = [Extent9].[Id]
WHERE [Project5].[Enabled] = 1
) AS [Filter5]
WHERE [Filter5].[IsAdminVerified1] = 1
) AS [Filter6]
WHERE [Filter6].[IsEmailVerified1] = 1
) AS [Filter7]
WHERE ([Filter7].[BannedEndDate1] IS NULL) OR ( CAST( SysDateTime() AS datetime2) > [Filter7].[BannedEndDate2])
) AS [Filter8]
WHERE [Filter8].[row_number] > 0
ORDER BY [Filter8].[Sponsored] DESC, [Filter8].[C2] DESC, [Filter8].[C3] DESC, [Filter8].[C1] DESC, [Filter8].[DateAdded] DESC
Linq:
(from website in _unitOfWorkRepository.WebsitesRepository.GetAll()
let amountVotes = website.WebsiteIn.Count(x => x.Unique)
let ratings = website.WebsiteRating.Select(x => x.Rating)
let avgRate = ratings.Any() ? (int)ratings.Average() : 5
let amountRedirects = website.WebsiteOut.Count(x => x.Unique)
where
website.Enabled && website.Users.IsAdminVerified && website.Users.IsEmailVerified &&
(website.Users.BannedEndDate == null || DateTime.Now > website.Users.BannedEndDate)
orderby website.Sponsored descending,
amountVotes descending,
amountRedirects descending,
avgRate descending,
website.DateAdded descending
select website);
數據庫邏輯:
我發現了一個龐大的查詢,只包含很少的邏輯。
完全沒有,它包含很多邏輯:
let
各自引起聚合子查詢的let
語句。 let
語句結果的orderby
子句 為了使SQL語句能夠按子查詢結果排序,應嵌套SELECT
語句。 如果沒有嵌套,則需要在ORDER BY
短語中重復聚合查詢。 因此,不管您相信與否,這已經是某種程度上經過優化的查詢形式。
為什么選擇這么多列
最終結果是完整的Website
對象的列表,因此對應表中的所有列都應出現在結果集中。 這些列最終源自最內部的查詢。
因此,其中沒有太多可以輕松優化的方法,尤其是。 而不是查詢生成器。
如果查詢導致您遇到性能問題,則可以考慮
Website
對象,而是屬性較少的類型)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.