I'm implementing a user search function in SQL/C#. I'm having a bit of trouble with the logistics of the function itself and I'm looking for some guidance.
I've been using a triple-nested subquery, which I feel is running a bit slow (avg 280-300ms to pull results from 1000 records in a Users table).
I first want to search by attributes for users (a separate table), then search based on location. I then want distance calculated and sorted, then only the closest 10 records brought back at a time (paged results).
Am I using the correct approach using a triple nested subquery? Or is there a standard or guiding principle to do this sort (pun not intended) kind of thing?
Code sample:
SELECT * FROM
(SELECT *, ROW_NUMBER()
OVER (ORDER BY UsersSubquery.Distance ASC) as RowNumber
FROM
(
SELECT TOP 100 PERCENT UsersSubquery.*,
(((geography::Point(UsersLocationsSubquery.Latitude, UsersLocationsSubquery.Longitude, 4326)).STDistance(@a)) / 1000) AS Distance
FROM Users UsersSubquery
INNER JOIN UsersAndAttributes ON UsersSubquery.UserId = UserAndAttributes.UserId
INNER JOIN UsersAndLocations AS UsersWithLocationsSubquery ON UsersSubquery.UserId = UsersWithLocationsSubquery.UserId
WHERE
(
((@Attribute1 = NULL) OR (UsersSubquery.Attribute1Id = @Attribute1))
AND
((@Attribute2 = NULL) OR (UsersSubquery.Attribute2Id = @Attribute2))
AND
((@Attribute3 = NULL) OR (UsersSubquery.Attribute3Id = @Attribute3))
AND
...etc
)
)
AS UsersSubquery )
Users
INNER JOIN Pictures ON Users.UserId = Pictures.UserId
WHERE RowNumber >= @StartRow and RowNumber <= @EndRow
Order by RowNumber