I have a table that records distance from Google/Bing between two valid UK postcodes. As the system is used, this table is added to so that the next distance query becomes fast and I do not have to call web services to retrieve distance(s) online.
Here is the table structure:
OID PostcodeA PostcodeB DistanceMeters DistanceMiles
-------------------- --------- --------- --------------------------------------- ---------------------------------------
1 BR60PS BT248DN 788847 490
2 BR60PS CM201JA 64426 40
3 BR60PS CM82AP 77640 48
4 BR60PS CO123AX 131617 82
5 BR60PS CT146EL 119366 74
6 BR60PS DA110TA 29247 18
7 BR60PS DE216AH 262570 163
8 BR60PS DL81AB 397524 247
9 BR60PS HG27JE 368802 229
10 BR60PS IP121AL 144394 90
11 BR60PS IP141AH 144183 90
12 BR60PS IP209AH 172259 107
Now I have a Scalar UDF that I use through Linq-to-SQL and it is defined as follows:
ALTER FUNCTION [dbo].[GetDistanceFromCache]
(@PostcodeA VARCHAR (MAX), @PostcodeB VARCHAR (MAX))
RETURNS DECIMAL
AS
BEGIN
DECLARE @FoundDistance AS DECIMAL;
SELECT @FoundDistance = DistanceMiles
FROM AddressInfoRecordedDistance
WHERE (PostcodeA = @PostcodeA
AND PostcodeB = @PostcodeB)
OR (PostcodeB = @PostcodeA
AND PostcodeA = @PostcodeB);
RETURN ISNULL(@FoundDistance, -1);
END
I need to know if there is a any faster SQL statement or c# linq to obtain the result? If I retrieve 800 employees and run them against 50 jobs, the system goes into a pause and if I don’t add the DBContext.GetDistanceFromCache() to the set of selects, the time taken is reduced quite significantly.
And here is the stalling query:
var query =
from locum in DbContext.Locums
where
locum.IsActive == true &&
locum.IsAdminMarkedComplete == true &&
locum.IsLocumsExciteBan == false &&
locum.IsGPHCBan == false &&
filterID1.Contains(locum.OID) == false &&
filterID2.Contains(locum.OID) == false
select new {
LocumID = locum.OID,
LocumName = locum.FirstName + " " + locum.LastName,
locum.MobileNumber,
locum.Email,
Gender = locum.Gender ? "Male" : "Female",
locum.DateofBirth,
LocumType = locum.LocumType.Name,
**Distance** = DbContext.GetDistanceFromCache(_Postcode, locum.AddressInfo.Postcode),
Address = String.Format("{0} {1} {2} {3}",
locum.AddressInfo.House.Length == 0 ? String.Empty : locum.AddressInfo.House + ", ",
locum.AddressInfo.Street.Length == 0 ? String.Empty : locum.AddressInfo.Street + ", ",
locum.AddressInfo.Area.Length == 0 ? String.Empty : locum.AddressInfo.Area + ", ",
locum.AddressInfo.Postcode ?? String.Empty),
Postcode = locum.AddressInfo.Postcode,
City = locum.AddressInfo.City.Name,
County = locum.AddressInfo.City.County.Name,
locum.SystemUserID
};
I think your query is slow because the DB has to be called each time the LINQ query does
select new { ... }, which is as many times as you have result rows.I would download the data from the table
AddressInfoRecordedDistancebefore matching the result set to it. I’m thinking something like this:And there you have it. Of course, you also need the
GetDistanceFromCachemethod:Of course, if you are running all of the above a lot of times, you should cache the variable
airds.