The problem is getting worse for me. I've now tried running my fixed query on larger data files and it is now slower than the original query.
If I call a Sub-Query by doing:-
(SELECT VehicleID FROM dbo.VehicleAllocations WHERE StartDate = dbo.JobDates.StartDate AND AllocationID = dbo.Allocations.AllocationID) AS VehicleID
This is much slower than calling a UDF which effectively does the same thing:-
dbo.GetVehicleID(dbo.JobDates.StartDate, dbo.Allocations.AllocationID) AS VehicleID
The UDF looks like this...
CREATE FUNCTION [dbo].[GetVehicleID] (@StartDate datetime. @AllocationID int)
RETURNS varchar(10) AS
BEGIN
DECLARE @VehicleID varchar(10)
SELECT @VehicleID = VehicleID FROM dbo.VehicleAllocations
WHERE StartDate = @StartDate AND AllocationID = @AllocationID
RETURN @VehicleID
END
If I compare 2 queries, one which calls 3 UDF's similar to the above and another which calls 3 sub-queries and do a simple WHERE clause, the UDF query takes 2 seconds and the Sub-query method takes 13 seconds.
I can't figure out why something which on the face of it look as though it is doing something pretty identical is so different, and only on SQL Server 2005.
?
Chris,
Again, what are you seeing in the execution plan? "Slower" doesn't mean much to me. Are you seeing a hash match
instead of a nested loop operation (which I'd assume you'd see with the
UDF)? What kind of indexes are in place?
Also, you say: size=3>"size=3>one which calls 3 UDF's similar to the above" -- why are you calling 3 of the same UDF in the query? Why not merge the three calls into one?
Sounds like you're using a lot of extra resources in this query, either on 2000
or 2005 -- just that 2005 is highlighting the problem (which, as I mentioned
before, is not an uncommon situation; you just need to learn how to work with it
a bit differently.)
style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
This post has been edited either by the author or a moderator in the Microsoft
Forums: http://forums.microsoft.com
The problem is getting worse for me. I've now tried running my fixed
query on larger data files and it is now slower than the original query.
If I call a Sub-Query by doing:-
(SELECT VehicleID FROM dbo.VehicleAllocations WHERE StartDate =
dbo.JobDates.StartDate AND AllocationID = dbo.Allocations.AllocationID) AS
VehicleID
This is much slower than calling a UDF which effectively does the same
thing:-
dbo.GetVehicleID(dbo.JobDates.StartDate, dbo.Allocations.AllocationID) AS
VehicleID
The UDF looks like this...
CREATE FUNCTION [dbo].[GetVehicleID] (@StartDate datetime. @AllocationID
int)
RETURNS varchar(10) AS
BEGIN
DECLARE @VehicleID
varchar(10)
SELECT @VehicleID = VehicleID FROM dbo.VehicleAllocations
WHERE StartDate = @StartDate AND AllocationID = @AllocationID
RETURN
@VehicleID
END
If I compare 2 queries, one which calls 3 UDF's similar to the above
and another which calls 3 sub-queries and do a simple WHERE clause, the UDF
query takes 2 seconds and the Sub-query method takes 13 seconds.
I can't figure out why something which on the face of it look as though it
is doing something pretty identical is so different, and only on SQL Server
2005.
Sorry, for just saying slower. It's a confusing thing this when I am convinced i've tried something earlier and had different results. Time for a break I think and think about it fresh tomorrow!
I've now tried 3 different approaches.
Method 1 - Multiple sub queries
Method 2 - The original query with multiple UDF's
Method 3 - A derived table as a sub query joining to another query to get the values from all of the UDF's used in Method 2.
Method 3 has seen best results generally but not with large data files. Using these data files the query plan has the following results:-
Method 1 - Lots of nested loops plus clustered index scans
Method 2 - A hash match (34%), merge inner join (18%), clustered index scan 30%, + more index scans
Method 3 - A hash match (23%), hash match (16%), Distinct sort (10%) + mix of clustered index scans and merge joins
Method 1 takes 95% of the batch, Method 2 takes 1% and Method 3 takes 4% on this set of data.
NNTP User wrote: |
| ? Chris, Again, what are you seeing in the execution plan? "Slower" doesn't mean much to me. Are you seeing a hash match instead of a nested loop operation (which I'd assume you'd see with the UDF)? What kind of indexes are in place? Also, you say: "one which calls 3 UDF's similar to the above" -- why are you calling 3 of the same UDF in the query? Why not merge the three calls into one? Sounds like you're using a lot of extra resources in this query, either on 2000 or 2005 -- just that 2005 is highlighting the problem (which, as I mentioned before, is not an uncommon situation; you just need to learn how to work with it a bit differently.) |
|
I will work on doing the table schema and sample data. Firstly here are the results on the SET STATISTICS IO ON...
Table 'Drivers'. Scan count 0, logical reads 1800, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ContractDriverAllocations'. Scan count 3, logical reads 12441, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'DriverTypes'. Scan count 1, logical reads 722, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Vehicles'. Scan count 0, logical reads 2958, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ContractVehicleAllocations'. Scan count 1, logical reads 6023, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'VehicleTypes'. Scan count 1, logical reads 714, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ContractDates'. Scan count 1, logical reads 3411, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ContractMovements'. Scan count 1, logical reads 306, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Clients'. Scan count 1, logical reads 8, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Contracts'. Scan count 1, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ContractDrivers'. Scan count 1, logical reads 95, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ContractVehicles'. Scan count 1, logical reads 61, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.