I'm running a query to fetch a users profile. The query get the users details, as well as all the reviews they have posted, as well as the comments in the reviews.
It may well be a case of I'm trying to get back too much, but as the api is getting called from mobile, I'd rather get as much as I can in one network call rather than making multiple network calls.
At the moment this is generating some really long sql, and takes around 25 seconds!
Any tips on how to improve it, or whether projections are even right way to do it
public UserVM GetUserInfo(string userId, string currentUserId)
{
var results =
from u in context.AspNetUsers
where u.Id == userId
select new UserVM
{
Name = u.UserName, Id = u.Id, ProfilePic = u.ProfilePicUrl, FollowerCount = u.Followers.Count, FollowingCount = u.Following.Count,
MemberSince = u.RegisteredDate,
RatingsCount = u.Ratings.Count(x => x.IsDeleted!=true),
FollowedByCurrentUser = currentUserId != null && u.Followers.Any(x => x.FollowedByUserId == currentUserId && x.UserId == userId),
reviews =
from r in u.Ratings
where r.IsDeleted != true
&& r.IsDraft != true
select new RatingVM()
{
ratingId = r.Id,
author_name = r.User.UserName,
userId = r.UserId,
profile_photo_url = r.User.ProfilePicUrl,
rating = r.RatingValue,
text = r.RatingComment,
created = r.Created,
likeCount = r.RatingLikes.Count(x => x.IsLiked && x.RatingId == r.Id),
likedByCurrentUser = currentUserId != null && r.RatingLikes.Any(x => x.IsLiked && x.RatingId == r.Id && x.UserId == currentUserId),
photos = from ri in r.RatingImages
select new PhotoVM { Id = ri.Id, width = 0, height = 0, photo_reference = ri.PhotoUrl, isMember = true, googlePlaceId = r.Place.GooglePlaceId, placeName = r.Place.Name },
comments = from c in r.Comments
where c.IsDeleted != true
select new CommentVM { commentId = c.Id, Created = c.Created, CommentText = c.CommentText, RatingId = r.Id , UserName = c.User.UserName, ProfilePicUrl = c.User.ProfilePicUrl, userId = c.UserId }
}
};
return results.FirstOrDefault();
}
SELECT
[Project17].[C1] AS [C1],
[Project17].[UserName] AS [UserName],
[Project17].[Id] AS [Id],
[Project17].[ProfilePicUrl] AS [ProfilePicUrl],
[Project17].[C32] AS [C2],
[Project17].[C33] AS [C3],
[Project17].[RegisteredDate] AS [RegisteredDate],
[Project17].[C34] AS [C4],
[Project17].[C2] AS [C5],
[Project17].[C31] AS [C6],
[Project17].[C4] AS [C7],
[Project17].[C5] AS [C8],
[Project17].[C6] AS [C9],
[Project17].[C7] AS [C10],
[Project17].[C8] AS [C11],
[Project17].[C9] AS [C12],
[Project17].[C10] AS [C13],
[Project17].[C11] AS [C14],
[Project17].[C12] AS [C15],
[Project17].[C13] AS [C16],
[Project17].[C14] AS [C17],
[Project17].[C3] AS [C18],
[Project17].[C15] AS [C19],
[Project17].[C16] AS [C20],
[Project17].[C17] AS [C21],
[Project17].[C18] AS [C22],
[Project17].[C19] AS [C23],
[Project17].[C20] AS [C24],
[Project17].[C21] AS [C25],
[Project17].[C22] AS [C26],
[Project17].[C23] AS [C27],
[Project17].[C24] AS [C28],
[Project17].[C25] AS [C29],
[Project17].[C26] AS [C30],
[Project17].[C27] AS [C31],
[Project17].[C28] AS [C32],
[Project17].[C29] AS [C33],
[Project17].[C30] AS [C34]
FROM ( SELECT
[Limit1].[Id] AS [Id],
[Limit1].[UserName] AS [UserName],
[Limit1].[ProfilePicUrl] AS [ProfilePicUrl],
[Limit1].[RegisteredDate] AS [RegisteredDate],
[Limit1].[C1] AS [C1],
[Limit1].[C2] AS [C2],
[UnionAll1].[C1] AS [C3],
[UnionAll1].[Id] AS [C4],
[UnionAll1].[Id1] AS [C5],
[UnionAll1].[C2] AS [C6],
[UnionAll1].[C3] AS [C7],
[UnionAll1].[UserId] AS [C8],
[UnionAll1].[C4] AS [C9],
[UnionAll1].[RatingValue] AS [C10],
[UnionAll1].[RatingComment] AS [C11],
[UnionAll1].[Created] AS [C12],
[UnionAll1].[C5] AS [C13],
[UnionAll1].[C6] AS [C14],
[UnionAll1].[Id2] AS [C15],
[UnionAll1].[Id3] AS [C16],
[UnionAll1].[C7] AS [C17],
[UnionAll1].[C8] AS [C18],
[UnionAll1].[PhotoUrl] AS [C19],
[UnionAll1].[C9] AS [C20],
[UnionAll1].[GooglePlaceId] AS [C21],
[UnionAll1].[Name] AS [C22],
[UnionAll1].[C10] AS [C23],
[UnionAll1].[C11] AS [C24],
[UnionAll1].[C12] AS [C25],
[UnionAll1].[C13] AS [C26],
[UnionAll1].[C14] AS [C27],
[UnionAll1].[C15] AS [C28],
[UnionAll1].[C16] AS [C29],
[UnionAll1].[C17] AS [C30],
CASE WHEN ([UnionAll1].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C31],
[Limit1].[C3] AS [C32],
[Limit1].[C4] AS [C33],
[Limit1].[C5] AS [C34]
FROM (SELECT TOP (1)
@p__linq__4 AS [p__linq__4],
@p__linq__5 AS [p__linq__5],
[Project3].[Id] AS [Id],
[Project3].[UserName] AS [UserName],
[Project3].[ProfilePicUrl] AS [ProfilePicUrl],
[Project3].[RegisteredDate] AS [RegisteredDate],
1 AS [C1],
CASE WHEN ((@p__linq__1 IS NOT NULL) AND ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Followers] AS [Extent5]
WHERE ([Project3].[Id] = [Extent5].[UserId]) AND ([Extent5].[FollowedByUserId] = @p__linq__2) AND ([Extent5].[UserId] = @p__linq__3)
))) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C2],
[Project3].[C1] AS [C3],
[Project3].[C2] AS [C4],
[Project3].[C3] AS [C5]
FROM ( SELECT
[Project2].[Id] AS [Id],
[Project2].[UserName] AS [UserName],
[Project2].[ProfilePicUrl] AS [ProfilePicUrl],
[Project2].[RegisteredDate] AS [RegisteredDate],
[Project2].[C1] AS [C1],
[Project2].[C2] AS [C2],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Ratings] AS [Extent4]
WHERE ([Project2].[Id] = [Extent4].[UserId]) AND (1 <> [Extent4].[IsDeleted])) AS [C3]
FROM ( SELECT
[Project1].[Id] AS [Id],
[Project1].[UserName] AS [UserName],
[Project1].[ProfilePicUrl] AS [ProfilePicUrl],
[Project1].[RegisteredDate] AS [RegisteredDate],
[Project1].[C1] AS [C1],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Followers] AS [Extent3]
WHERE [Project1].[Id] = [Extent3].[FollowedByUserId]) AS [C2]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[UserName] AS [UserName],
[Extent1].[ProfilePicUrl] AS [ProfilePicUrl],
[Extent1].[RegisteredDate] AS [RegisteredDate],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Followers] AS [Extent2]
WHERE [Extent1].[Id] = [Extent2].[UserId]) AS [C1]
FROM [dbo].[AspNetUsers] AS [Extent1]
WHERE [Extent1].[Id] = @p__linq__0
) AS [Project1]
) AS [Project2]
) AS [Project3] ) AS [Limit1]
OUTER APPLY (SELECT
CASE WHEN ([Filter10].[Id1] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],
[Project9].[Id] AS [Id],
[Project9].[Id] AS [Id1],
[Project9].[C1] AS [C2],
[Project9].[C2] AS [C3],
[Project9].[UserId] AS [UserId],
[Project9].[C3] AS [C4],
[Project9].[RatingValue] AS [RatingValue],
[Project9].[RatingComment] AS [RatingComment],
[Project9].[Created] AS [Created],
[Project9].[C5] AS [C5],
[Project9].[C4] AS [C6],
[Filter10].[Id1] AS [Id2],
[Filter10].[Id1] AS [Id3],
CASE WHEN ([Filter10].[Id1] IS NULL) THEN CAST(NULL AS int) ELSE 0 END AS [C7],
CASE WHEN ([Filter10].[Id1] IS NULL) THEN CAST(NULL AS int) ELSE 0 END AS [C8],
[Filter10].[PhotoUrl] AS [PhotoUrl],
CASE WHEN ([Filter10].[Id1] IS NULL) THEN CAST(NULL AS bit) ELSE cast(1 as bit) END AS [C9],
[Filter10].[GooglePlaceId] AS [GooglePlaceId],
[Filter10].[Name] AS [Name],
CAST(NULL AS int) AS [C10],
CAST(NULL AS int) AS [C11],
CAST(NULL AS datetime2) AS [C12],
CAST(NULL AS varchar(1)) AS [C13],
CAST(NULL AS int) AS [C14],
CAST(NULL AS varchar(1)) AS [C15],
CAST(NULL AS varchar(1)) AS [C16],
CAST(NULL AS varchar(1)) AS [C17]
FROM (SELECT
[Project7].[Id] AS [Id],
[Project7].[RatingValue] AS [RatingValue],
[Project7].[RatingComment] AS [RatingComment],
[Project7].[Created] AS [Created],
[Project7].[PlaceId] AS [PlaceId],
[Project7].[UserId] AS [UserId],
[Limit1].[UserName] AS [C1],
N'' AS [C2],
[Limit1].[ProfilePicUrl] AS [C3],
CASE WHEN ((@p__linq__4 IS NOT NULL) AND ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[RatingLikes] AS [Extent8]
WHERE ([Project7].[Id] = [Extent8].[RatingId]) AND ([Extent8].[IsLiked] = 1) AND ([Extent8].[RatingId] = [Project7].[Id]) AND ([Extent8].[UserId] = @p__linq__5)
))) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C4],
[Project7].[C1] AS [C5]
FROM ( SELECT
[Project6].[Id] AS [Id],
[Project6].[RatingValue] AS [RatingValue],
[Project6].[RatingComment] AS [RatingComment],
[Project6].[Created] AS [Created],
[Project6].[PlaceId] AS [PlaceId],
[Project6].[UserId] AS [UserId],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[RatingLikes] AS [Extent7]
WHERE ([Project6].[Id] = [Extent7].[RatingId]) AND ([Extent7].[IsLiked] = 1) AND ([Extent7].[RatingId] = [Project6].[Id])) AS [C1]
FROM ( SELECT
[Extent6].[Id] AS [Id],
[Extent6].[RatingValue] AS [RatingValue],
[Extent6].[RatingComment] AS [RatingComment],
[Extent6].[Created] AS [Created],
[Extent6].[PlaceId] AS [PlaceId],
[Extent6].[UserId] AS [UserId]
FROM [dbo].[Ratings] AS [Extent6]
WHERE ([Limit1].[Id] = [Extent6].[UserId]) AND (1 <> [Extent6].[IsDeleted]) AND (1 <> [Extent6].[IsDraft])
) AS [Project6]
) AS [Project7] ) AS [Project9]
OUTER APPLY (SELECT [Extent9].[Id] AS [Id1], [Extent9].[PhotoUrl] AS [PhotoUrl], [Project10].[Name] AS [Name], [Project10].[GooglePlaceId] AS [GooglePlaceId]
FROM [dbo].[RatingImages] AS [Extent9]
LEFT OUTER JOIN (SELECT
[Extent10].[Id] AS [Id],
[Extent10].[Name] AS [Name],
[Extent10].[GooglePlaceId] AS [GooglePlaceId]
FROM [dbo].[Places] AS [Extent10]
WHERE [Project9].[PlaceId] = [Extent10].[Id] ) AS [Project10] ON 1 = 1
WHERE [Project9].[Id] = [Extent9].[RatingId] ) AS [Filter10]
UNION ALL
SELECT
2 AS [C1],
[Project15].[Id] AS [Id],
[Project15].[Id] AS [Id1],
[Project15].[C1] AS [C2],
[Project15].[C2] AS [C3],
[Project15].[UserId] AS [UserId],
[Project15].[C3] AS [C4],
[Project15].[RatingValue] AS [RatingValue],
[Project15].[RatingComment] AS [RatingComment],
[Project15].[Created] AS [Created],
[Project15].[C5] AS [C5],
[Project15].[C4] AS [C6],
CAST(NULL AS int) AS [C7],
CAST(NULL AS int) AS [C8],
CAST(NULL AS int) AS [C9],
CAST(NULL AS int) AS [C10],
CAST(NULL AS varchar(1)) AS [C11],
CAST(NULL AS bit) AS [C12],
CAST(NULL AS varchar(1)) AS [C13],
CAST(NULL AS varchar(1)) AS [C14],
[Join2].[Id2] AS [Id2],
[Join2].[Id2] AS [Id3],
[Join2].[Created] AS [Created1],
[Join2].[CommentText] AS [CommentText],
[Project15].[Id] AS [Id4],
[Join2].[UserName] AS [UserName],
[Join2].[ProfilePicUrl] AS [ProfilePicUrl],
[Join2].[UserId] AS [UserId1]
FROM (SELECT
[Project13].[Id] AS [Id],
[Project13].[RatingValue] AS [RatingValue],
[Project13].[RatingComment] AS [RatingComment],
[Project13].[Created] AS [Created],
[Project13].[UserId] AS [UserId],
[Limit1].[UserName] AS [C1],
N'' AS [C2],
[Limit1].[ProfilePicUrl] AS [C3],
CASE WHEN ((@p__linq__4 IS NOT NULL) AND ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[RatingLikes] AS [Extent13]
WHERE ([Project13].[Id] = [Extent13].[RatingId]) AND ([Extent13].[IsLiked] = 1) AND ([Extent13].[RatingId] = [Project13].[Id]) AND ([Extent13].[UserId] = @p__linq__5)
))) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C4],
[Project13].[C1] AS [C5]
FROM ( SELECT
[Project12].[Id] AS [Id],
[Project12].[RatingValue] AS [RatingValue],
[Project12].[RatingComment] AS [RatingComment],
[Project12].[Created] AS [Created],
[Project12].[UserId] AS [UserId],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[RatingLikes] AS [Extent12]
WHERE ([Project12].[Id] = [Extent12].[RatingId]) AND ([Extent12].[IsLiked] = 1) AND ([Extent12].[RatingId] = [Project12].[Id])) AS [C1]
FROM ( SELECT
[Extent11].[Id] AS [Id],
[Extent11].[RatingValue] AS [RatingValue],
[Extent11].[RatingComment] AS [RatingComment],
[Extent11].[Created] AS [Created],
[Extent11].[UserId] AS [UserId]
FROM [dbo].[Ratings] AS [Extent11]
WHERE ([Limit1].[Id] = [Extent11].[UserId]) AND (1 <> [Extent11].[IsDeleted]) AND (1 <> [Extent11].[IsDraft])
) AS [Project12]
) AS [Project13] ) AS [Project15]
INNER JOIN (SELECT [Extent14].[Id] AS [Id2], [Extent14].[CommentText] AS [CommentText], [Extent14].[Created] AS [Created], [Extent14].[RatingId] AS [RatingId], [Extent14].[IsDeleted] AS [IsDeleted], [Extent14].[UserId] AS [UserId], [Extent15].[UserName] AS [UserName], [Extent15].[ProfilePicUrl] AS [ProfilePicUrl]
FROM [dbo].[Comments] AS [Extent14]
INNER JOIN [dbo].[AspNetUsers] AS [Extent15] ON [Extent14].[UserId] = [Extent15].[Id] ) AS [Join2] ON ([Project15].[Id] = [Join2].[RatingId]) AND (1 <> [Join2].[IsDeleted])) AS [UnionAll1]
) AS [Project17]
ORDER BY [Project17].[Id] ASC, [Project17].[C31] ASC, [Project17].[C5] ASC, [Project17].[C3] ASC